-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Why are the reactive versions of Quarkus and Helidon so slow to start? #5
Comments
The slow startup seems to be caused by the frameworks fetching the issuer or JWKS URI on startup. If I turn off my internet and run
Same with Helidon:
Since these frameworks are supposed to be as fast as possible for serverless environments, I think they do this processing on the first request rather than on startup. For some background, when I first started this comparison a couple of years ago, Spring Security and Helidon did the same thing (processing on startup instead of first request). They both switched to processing on the first request. |
Not sure it makes any difference, but you could re-write the quarkus @Path("/hello")
public class HelloResource {
@Inject
SecurityIdentity securityIdentity;
@GET
@Path("/")
@Authenticated
@Produces(MediaType.TEXT_PLAIN)
@NonBlocking
public String hello() {
return "Hello, " + securityIdentity.getPrincipal().getName() + "!";
}
} You don't need to explicitly return a |
Thanks for the code review, @edeandrea! I added your suggested change in ee7b4ce. I discovered why Quarkus reactive is slow to start. It's because it's looking up the issuer rather than doing it lazily. Please take a look at my comment above for more information. |
I think I have a way around that. Try adding this to # https://quarkus.io/guides/all-config#quarkus-oidc_quarkus.oidc.jwks.resolve-early
quarkus.oidc.jwks.resolve-early=false
# https://quarkus.io/guides/all-config#quarkus-oidc_quarkus.oidc.discovery-enabled
quarkus.oidc.discovery-enabled=false
# https://quarkus.io/guides/all-config#quarkus-oidc_quarkus.oidc.jwks-path
quarkus.oidc.jwks-path=${quarkus.oidc.auth-server-url}/.well-known/jwks.json This is what I get now:
|
I also downgraded to 3.6.7 because 3.7 hasn't yet been released. That version switch may or may not have any effect. |
switching to 3.7.1 also seems to work fine and produce similar results, even if it hasn't yet been released. |
Also, using |
@edeandrea @mraible thanks, Using dynamic tenant resolver can complement it: https://quarkus.io/guides/security-openid-connect-multitenancy#tenant-config-resolver - for the bearer single tenant case one can just implement it as:
The config resolution will take time at the first request |
Thanks for the fix, @edeandrea! Personally, I think these settings should be the default and you should have to turn on startup discovery. Regarding the 3.7.1 version, I get that when creating a new project with the Quarkus CLI:
@sberyozkin If I remove the
Since printing this message will likely slow startup, I'll keep using the property. Update: Start time for Quarkus: (45 + 41 + 42 + 44 + 49) / 5 = 44.2 |
I would tend to agree. @sberyozkin is the right person to answer as to why it is the way it is. |
Reopening since Helidon is still slow to start, even after #6. (183 + 265 + 177 + 386 + 303) / 5 = 262.8 |
For projects that always want to be on the bleeding edge, using <quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id> gets around this problem |
So, the OIDC server is indeed may not be available at the startup time ? That is fine then, Quarkus will attempt to reconnect at the first request, but I guess at the demo level it may be of some concern.
As I said earlier, you can try removing everything from the application properties and have the following bean in the project:
At least please keep this option in mind.
IMHO it is important to be able to know at the prod startup time if the OIDC server is actually available. We have 2 options, one which Matt is currently using, and the one I've just typed, that can give users all the flexibility. Cheers |
Quarkus Reactive takes 7x longer to start: 353ms vs 49.4.
Helidon SE takes 5x longer: 303.6ms vs 59.4.
Startup time
Imperative
M: (36 + 48 + 36 + 47 + 42) / 5 = 41.8
Q: (55 + 46 + 44 + 54 + 48) / 5 = 49.4
S: (67 + 70 + 65 + 66 + 54) / 5 = 64.4
H: (64 + 55 + 61 + 58 + 59) / 5 = 59.4
Reactive
M: (52 + 45 + 47 + 46 + 47) / 5 = 47.4
Q: (359 + 291 + 276 + 534 + 305) / 5 = 353
S: (55 + 72 + 62 + 52 + 52) / 5 = 58.6
H: (239 + 239 + 509 + 263 + 268) / 5 = 303.6
Imperative with Virtual Threads
Q: (44 + 38 + 46 + 43 + 45) / 5 = 43.2
S: (71 + 64 + 68 + 71 + 66) / 5 = 68
Steps to reproduce
Install GraalVM 21:
For imperative:
The last script takes an argument of
micronaut
,quarkus
,spring-boot
, orhelidon
.For reactive:
For virtual threads:
I only calculated the startup times for Quarkus and Spring Boot because they're the only apps modified in the
virtual-threads
branch.Memory usage (in MB):
Imperative
Imperative with Virtual Threads
Reactive
The text was updated successfully, but these errors were encountered: