Last year, I did a talk at try! Swift NYC on the state of Swift on Server in 2018. Since then, Swift on Server has evolved quite a bit. This blog post is my opinion on where Swift on Server stands at the end of 2019.

Progress

In my talk last year, I pointed out several building blocks that were missing in the Swift on Server ecosystem. Of these, several have already been addressed. We now have Swift Log, Swift Metrics, Swift Prometheus, and several other building blocks in place.

IBM

The Swift Server Working Group recently announced that IBM will no longer be working on Swift on Server. It isn’t yet clear what will happen to Kitura, but I think it’s safe to assume Kitura’s days are numbered.

I believe this will be a substantial blow to the Swift on Server community. I had the good fortune to meet Chris and Ian at try! Swift. I’ve also had the privilege to get to know a few people who work on Swift on Linux right here in Bangalore. It’s unclear whether they will also be pulling back from the Swift community. These are great folks, and it’s rather unfortunate to hear that they will no longer be participating in the community.

However, I must admit, this isn’t entirely surprising. Kitura’s approach to Swift on Server appeared for the most part to be to go head to head with Java, NodeJS, etc. This always felt like a mistake to me. Given the limited resources behind Swift on Server, it was always going to be incredibly unlikely that Swift would ever catch up to the long standing & thriving ecosystems that surround other server side languages, like Java, Ruby, Python, JavaScript, etc.

So if Swift can’t really catch up to other ecosystems, why even bother trying?

Why Swift on Server?

The most common argument I’ve heard that is that iOS developers already know Swift, and it would be easy for them to transition to server programming. The second most common argument I’ve heard is that Swift on Server enables code sharing with iOS apps. In my opinion, these are both flawed arguments.

While the programming language being used to write server code is definitely a factor, it is a relatively insignificant factor. The problems & frameworks being used to solve those problems, ultimately are a lot more important. iOS developers aren’t not working on server code because they have to use Ruby, or Python. They’re not writing server code because most of the knowledge & experience they’ve gained is useless. All that UIKit knowledge you gained the hard way - totally useless. On top of this, you need to learn a ton about the server side ecosystem. How do you do deployments? How do you monitor in production? How do you deal with concurrency? How do you debug performance issues? Gaining this knowledge & experience is a lot harder than learning a new programming language. Therefore, my belief is that this reason was never going to drive Swift on Server adoption.

There are also multiple problems with the code sharing argument. First off, Swift still doesn’t officially run on Android, nor does it officially run on Windows, and as far as I’m aware, Swift’s WASM story still isn’t quite there. How many companies and teams do you know of that have only an iOS/macOS app, and a server, but no Android app, and no web app? It’s incredibly uncommon. Even if you’re on such a team that has only Apple front-ends, and a server component, what code would you realistically share? A few model objects? You could likely re-write those in a few hours or days. There’s not a lot of value in sharing this code. Besides, there’re better approaches to this sort of code sharing anyway: Protocol Buffers, gRPC, etc.

Having said all that though, I am still bullish on Swift on Server. However, for Swift on Server to gain adoption, I think it’s going to have to bring something to the table for folks who’re already server side developers today. I think Swift has a few things going for it that few other languages do when it comes to server side development.

Memory Safety Without Garbage Collection

Almost every popular server side language has both a VM/interpreter & garbage collection. While there are definitely advantages to both, they do have problems.

Garbage collected environments are unpredictable. It is quite common to end up with GC problems that are incredibly hard to reproduce. It’s also often hard to figure out whether you have a garbage problem, or a garbage collection problem. Using languages like C/C++ which do not have garbage collection comes with a major downside: lack of memory safety. Swift (due to its use of ARC), provides a fantastic middle ground - memory safe, and predictable.

Fast Startup Time

VMs are also quite slow to start. For example, it is not uncommon for a typical Java application to take several seconds (sometimes even minutes) to start up. This was a non-issue in the past, when you expected to have huge machines that ran processes which ran for days (even months), but in a cloud native world, this is a real problem. For example, in server less functions, a VM is a deathblow.

Performance

Swift is already quite fast 1, compared to languages like Ruby & Python for most use cases. It is also faster than Java in some cases. However, what excites me about Swift is that it can become an order of magnitude faster than most other languages. Swift’s type system, value types (with copy on write), static dispatch, the String APIs in the standard library, etc. have the potential to make Swift compete with a well tuned C program on performance. Unfortunately, that potential is not yet realized. Swift 5 & 5.1 bring brought some huge improvements though, and I’m optimistic about Swift competing on performance with systems programming languages in the near future.

Swift NIO

In a year, Swift NIO has also moved forward quite a bit. I believe NIO is Swift on Server’s biggest asset. Vapor has already adopted it in a big way. Postgres-NIO has been accepted by the SSWG. There aren’t many (any?) robust non-blocking database drivers that are easy to use in other languages yet. NIO provides a base to build on - if the Swift on Server community can leverage it successfully to build high performance web frameworks, with non-blocking database drivers, I believe it will be an incredibly compelling reason for server side developers to start using Swift.

Competition

Rust

In my opinion, Rust is the biggest competitor to the Swift on Server ecosystem. Rust is incredibly fast, memory safe, and is not garbage collected. It makes very similar tradeoffs on many fronts. The tooling ecosystem around it is quite mature as well. Tokio is very similar to NIO, and has recently announced support for async/await, which will be fantastic for developer ergonomics when higher level frameworks support it. Existing Rust frameworks are already much faster than Swift. While the war isn’t over yet, Rust has won several battles.

Kotlin

The biggest hurdle with Swift & Rust, is that they are relatively recent, and the ecosystems around them are still quite immature. For example, if you want to write a Microsoft Excel file using Swift/Rust, there really isn’t a great library for that yet. If you need to connect to an Oracle or MS SQL database, there isn’t a good way to do that in Swift/Rust yet. Where Kotlin shines, is with its interop with Java. Being able to seamlessly integrate with Java (and the vast ecosystem around it) is incredibly powerful. This makes Kotlin fully viable as a server side language today for almost everyone. However, in the long run, unless Kotlin Native (and the ecosystem around it) emerges strongly, I believe Swift & Rust will bring substantial improvements to server side development to convince a lot of people to use them over Kotlin.

Wishlist

Below are a few things I would like to see make Swift on Server viable:

  • Performance on par with (or better than) Rust.
  • async/await. This is a huge boost to developer ergonomics when dealing with non-blocking code. A framework like Vapor would be so much nicer to use with async/await.
  • A solution/mitigation to fatalError bringing down the entire process, instead of just killing a single request. For example, accessing an element in array that is out of bounds will result in the entire process dying, which could result in thousands of requests being dropped.
  • Robust non-blocking database drivers for popular relational databases (including databases like Microsoft SQL Server and Oracle, which are not open source).
  • Equivalent of Diesel that supports all the above databases.
  • Robust connection pooling library.

Update on 2020-01-04

The folks at Vapor announced that Vapor Cloud is shutting down. I don’t know what implication this has on the Vapor project (if any).

If you have any thoughts, comments or concerns, please let me know! I’m @gopalkri on Twitter.

  1. https://github.com/TechEmpower/FrameworkBenchmarks