Hummingbird 2

We're really pleased to announce the release of version 2 of Hummingbird.

This is a complete rebuild of the server framework, built on top of structured concurrency. This makes the code easy to read, maintain and reason about and this transfers to the backends built with it.

The framework includes

  • Flexible HTTP layer with support for HTTP1.1, TLS, HTTP2
  • Heavily optimized trie based router
  • Middleware for CORS, File serving and observability (logging, metrics and tracing).
  • Integration with latest version of swift-service-lifecycle and new swift-http-types.

Separate packages provide

  • Support for WebSockets, server upgrades and client connection.
  • An authentication framework
  • Redis/Fluent integration
  • Job Queue framework used to persist and offload work to other systems.
  • Rendering dynamic content using Mustache
  • HTTP decompression/compression middleware
  • Support for running inside an AWS Lambda

If you are at the ServerSide.swift conference in London @Joannis_Orlandos will be there doing an "Introducing Hummingbird 2" talk there. I'm sure he'd be happy to see you all.

57 Likes

Hey @Joannis_Orlandos will the talk be available as free video online?

1 Like

Congrats! looks like a really good option for building web services

1 Like

I think you meant to ping me: Yes the talk will be online after the conference.

5 Likes

Looks amazing! Love the integration with swift-service-lifecycle and swift-service-context Wondering what the recommendation is for testing i.e. XCTest vs. swift-testing?

1 Like

You can use either. Currently the internal tests for the project are XCTest as we support 5.9 onwards. But there should be no reason you can't use swift testing for a swift 6 project. The hummingbird test framework is written without any dependency on XCTest.

3 Likes

This is fantastic news! Looking forward to watching the introduction video from the conference.
I’m glad to see there’s a focus on serverless with AWS Lambda, would there happen to be any docs available on it?
And slightly related, I’ve been keeping my eye on this serverless deployment to Vercel which wraps the AWSLambaRuntime, do you envision a way this would be possible with Hummingbird V2?

In its current state, that package won't work with Hummingbird, simply because it's tied to Vapor 4. (This also means it won't work with Vapor 5 down the line).

However, looking at the contents of that package, it's very simple to implement Vercel's features on top of the existing HBLambda package.

You'd need to make define a Lambda function protocol that works with InvokeEvents, similar to what we do for APIGateway

After that you just need to map the InvokeEvent to a Request, and the Response needs to be returned in the right format for Vercel too. That's all that's needed to integrate a new lambda type with Hummingbird 2.

2 Likes

The Vercel package isn’t tied to Vapor, I just added an extra dep specifically for Vapor. Will be easy for me to add one for Hummingbird 2 as well

@AndrewBarba there’s no way to use this dependency without pulling in all of Vapor and its dependencies though.

@Joannis_Orlandos yes that’s true. What’s suggested way to have multiple sub-packages in one repo and only pull in deps from the package you need? Or is that a limitation of SPM and the Vapor and Hummingbird variants should be separate repos?

this is one of the oldest limitations of SwiftPM, however if i remember correctly, it clones dependencies lazily so if you’re using a product that includes that dependency, it should not be cloned.

1 Like

Congratulations! And thanks for all the thoughtful work.

2 Likes

Any chance we can see techempower benchmarks for v2. Current benchmarks seem like v1 and seems way down in pack

Currently performance is not up to what we hoped for Hummingbird 2 we are waiting on some changes in Swift before we improve that. With Hummingbird 1 we were able to keep request processing to a single EventLoop, as we have moved to Swift concurrency the ability to do this has been complicated. It is possible via custom executors but these have some performance issues which need to be resolved first.

As an aside I thought Hummingbird v1 did just fine in the TechEmpower benchmarks. We provided a balance of performance, features, safety and usability which is about right. Raw throughput is not the only thing to consider when choosing a framework. Of course it'd always be nicer to run faster and I did spend a considerable amount of time trying to improve performance. You'll notice Hummingbird v1 is the fastest of the swift frameworks outside of the raw SwiftNIO server.

3 Likes

You can see the latest results here ( 2024-10-19).
Unfortunately, Swift frameworks performance is disappointing.

1 Like

Swift won't do well at Techempower until it optimizes towards the benchmark like all of the top performers do. There are also a few fundamental bottlenecks that Swift may never fix, like the throughput of Codable, that limit its performance in web benchmarks.

Agreed, although as for Codable, we shouldn't need to use it for the json Techempower benchmark, we should be able to use anything that performs better (as long as it's generating the JSON dynamically).

Congrats on Hummingbird 2 BTW. It's looking awesome. I'm already using it in a few projects :clap: (started using it during the betas)

3 Likes
Currently performance is not up to what we hoped for Hummingbird 2 we are waiting on some changes in Swift before we improve that.

Hey Adam, thanks for your hard work on Hummingbird. Can you please elaborate on Swift features that you are waiting for? While it's true that raw throughput is not the only thing to consider when choosing a framework it's a good selling point.

Given Hummingbird is using structured concurrency throughout it is hitting a lot of new code paths in the standard library and server benchmarks are pushing them like nothing else does.

We would like to use custom task executors to control running tasks on EventLoops to reduce context switches (a considerable cost at the moment). Unfortunately this is not providing the performance improvement we had hoped for. There are optimisation possibilities here though related to memory allocations being made when continuations are resumed. We just need someone on the swift team to look at it.

EDIT: I've been informed the allocations on resuming a continuation is a general issue and not specific to custom task executors, it is just that custom task executors cause us to hit this code path more frequently.

4 Likes