Issues learned: 4 years with Server-side Swift

TL;DR

Server-side Swift has some big disadvantages comparing to other languages / frameworks and it is missing some key features (ecosystem, stability, tooling). There are some niches, where using Swift is a good solution, but very often it isn't.

Issues

Safety (one of the marketing advantages)

One of the advantages of Swift is safety. Yes, it removes a lot of possible issues, but it is still away from safe:

  • Low stack size on secondary threads (5120kb), the app will crash if the stack size isn't big enough: Increase size of stack
  • Lacy variables are not thread safe
  • Parts of the standard library still crash like: Dictionary(_:uniquingKeysWith:): Apple Developer Documentation
  • Crash for handling integer overflows

Special for Server-side applications a crash means always a downtime and has the potential of an incident for your service.
There are ways to minimise the issue like:

  • Proxy in front of the Swift application who detects such issue
  • Cache bad request
  • Restart Swift application fast with tools like supervisor
  • Load balancer
  • ...

But: It is a lot of extra work, there are no guidelines, it is complicated to find the reason of a crash, ...

Performance

It is possible to write fast Swift code, but it isn't easy.

Why I believe it is not easy:

Some of the issues are:

  • ARC: yes, we all love it, but counting the references costs time
  • Copy on Write and there is no easy way to find such places within the code: "High Performance Systems in Swift": High Performance Systems in Swift – Cory Benfield at Hacking with Swift Live 2019 - YouTube
  • Values <-> Classes: Its hard to understand the drawbacks (when it comes to performance). With classes you always have the issue of ARC and of the heap, with values you have issue of copying (special for large structures), you have the issue of a potential stack limit and the issue of references within values
  • There is no good documentation / guidelines when it comes to performance
  • There is no good way to measure the performance:
    • Instruments: Not possible to deal with big call stacks
    • The integrated performance tests are useless, because they are running without optimisation

It feels like: If you want to write fast Swift code you have to:

  • Write custom benchmark tools
  • Search for non-planned COWs
  • Find the right balance by using References or Values
  • Deal with pointers
  • (Non)performant operations are hidden to the engineers and you have to try them out

Swift will have a ownership model (like Rust) in the future and this will improve the situation of some of the issues.

Tooling

SPM

  • No possibility of already compiled libraries
  • No resource support
  • The checkout of dependencies stuck sometimes without any progress
  • Bad error messages if there is a typo in you Package.swift
  • The output of the tests is overwhelming, using --parallel help, but than it's hard to understand when a test was crashing
  • There are always some small issues like:
    • You need an empty LinuxMain.swift: Test discovery on Linux
    • We had a package with the name TestSupport, which clashed with the same named package of the SPM O_O
    • Running multiple tests with the filter option is slower than without

Xcode

  • You have to download >5GB for every release
  • The used Swift version in Xcode is not always in sync with the released version of Linux or apples docker image: GitHub - apple/swift-docker: Docker Official Image packaging for Swift
  • Limited SPM support
  • Limited Test support (disabling tests, running categories of tests, performance tests, ...)
  • Its hard to use other tools and very often they have other issues because they can't integrate it like apple (like AppCode or CLion)
  • Does not run on Linux, but when you main target is Linux this creates some extra work
  • Switching branches doesn't work well enough, sometimes only "Clean Product" and recreating the Xcode project helps

Compiler + Errors

  • The error messages of the Swift compiler are in the best case ok, sometimes a joke (too complex to be solved) and sometimes they lead you into a wrong direction, special when it comes to generics, function overloading
  • Slow compile times in general
  • The compile times are not predictable
    • Splitting up the code into modules has some advantages and disadvantages related to compilation times
    • The "good old" trick to combine all files into one still improves the compilation sometimes (SWIFT_WHOLE_MODULE_OPTIMIZATION=YES), even after the new build system
    • A change of one test case sometimes means you have to compile multiple minutes again

Ecosystem

The Server-side Swift community was always a niche and it feels like it hasn't grown a lot.
If there is an issue which is not covered by the starting tutorials you are very often alone with it. The Swift forum is at least a good place to get in contact and have one first place to follow the discussions.

There is no easy way to find package and many packages are abandoned. There are still some good packages and in some of them you see the enthusiasm behind their project. But after IBM left the Swift ecosystem, is there any other big player in it? Is Apple able to drive such process, special with the lack of exchange with the community (I only say SwiftUI).

I'm aware that some of the issues are because of the age of the language. At some parts you can see improvements like:

Conclusion

A lot of the claimed advantages (safety, performance) are true comparing to objective c, but not when you compare it with more mature languages like Java/Kotlin/Scale, node or elixir/erlang.
I don't want to say that you should not use Swift on the server, but Swift on the server has some pain points and you should be aware of it.

I still feel that Server-side Swift has a big potential but on the other hand I'm not sure if swift has to be everywhere. Swift has already started with a big backpack ((objective) c compatibility, fast as c, tools / environment to create apps, apple has big impact on the development, ...). Running it on a different OS and for a different reason is a challenge and comes with a cost.

Out of this post I can easily create a whish list how to improve the situation. And I hope Apple is taking the Server-side Community more serious and improve some of the situation. Some the issues can possibly be improved by the community, but I have the feeling that the community already has to do a lot of stuff.

Background

We are using Server-side Swift since more than 4 years. This means:

  • We started to migrate our Swift Code to run on Linux with the first Swift snapshot for Linux (October 2016)
  • We were using it on production since Swift DEVELOPMENT-SNAPSHOT-2016-03-01-a
  • We have gone through all the pain of:
    • Migrating code from one Swift version to the next one
    • Bugs which existed only on Linux
    • Non existing Swift mature Web Frameworks
  • Our application: Mathematical application within a docker container behind a web framework. > 120.000 loc and over 11.000 tests
30 Likes

It seems Vapor is now taking the lead in server-side, along with Apple, and I do hope Apple can attach more attention to this field. The SwiftUI case is somehow depressing many community members.

Also looking forward to the wider platform support, which is declared in the roadmap of Swift 5.3 and 6. However, as some members have already commented, we also need better performance, which can be a critical point in many areas. And server-side usage does require easier cross-platform migration and development process, which includes better tooling, documents, etc.

All in all, Swift still has a long way to go before finally gaining a stable position among the server-side players, in which Apple ought to do something to improve at least the documentation and tools. Also, performance and stability issues should be paid more attention to, which is critical to server-side.

3 Likes

Do note that Swift considers crashing to always be safe.

Thus, I think that the only safety concern on that list is lazy variable thread safety.

Therefore it would probably be better labeled as “Reliability”, which IIRC, Swift does not promise.

3 Likes

Do note that Swift considers crashing to always be safe.
Thus, I think that the only safety concern on that list is lazy variable thread safety.
Therefore it would probably be better labeled as “Reliability”, which IIRC, Swift does not promise.

You are right, I mixed some "safety" definitions here and for some parts reliability would be a better word. But special for server apps this is a key requirement.

yes, vapor was always trying to improve and I hope that if apple is using more swift too (outside of mobile-apps development ), they feel some of the pain too and improve some of the situations.
Perhaps I'm too critical at the current situation and it takes only longer than I would like to :D

3 Likes

I agree. I'm trying to build a package four releases already (5.1.4, 5.1.5, 5.2, 5.2.1) - and see bugs. project is not ready to prepare stable packages even with patches. and no feedback on the forum.

1 Like

I’ll comment on some of the other points later, but I think this is something we all hate. It’s absurd that every minor Xcode update needs such a massive download.

Imagine how many tens (hundreds?) of millions of developers there are around the world, including CI servers and whatnot, downloading all of those bits. It’s computationally and environmentally really wasteful, as well as an enormous PITA.

4 Likes

I apologise for a somewhat unhelpful message here, but it's important to consider even a greater amount of developers around the world that don't have access to bandwidth, storage and other resources to work with these enormous packages. I understand that Linux builds are smaller, but I don't think that package size was ever mentioned as a priority. It's a bit unfair when you look at the pitch:

Welcome to the Swift community. Together we are working to build a programming language to empower everyone to turn their ideas into apps on any platform.

Apparently, "everyone" here means "rich enough to buy macOS hardware to get the best experience, and even if you're on Linux you still need to have enough bandwidth to download all the tooling". I don't want to be snarky, but I think we as a community should break our own privilege bubble and prioritise this if we ever want Swift to get wider adoption.

18 Likes

Thanks for the in depth feedback on server side swift. It's always great to get some insight into the server side venture after long usage. Thanks for the post.

3 Likes