You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
StytchClient holds OkHttpClient and CoroutineScope but has no close() to release them #148
com.stytch.java.consumer.StytchClient (and B2BClient) holds resources that need explicit cleanup but exposes no way to release them. Applications that hold a single StytchClient for the entire process lifetime are fine — anything that creates a StytchClient per tenant, per test, or per config reload leaks until the JVM exits.
What's held
From the bytecode of StytchClient in sdk-11.0.0:
private final kotlinx.coroutines.CoroutineScope coroutineScope;
private final com.stytch.java.http.HttpClient httpClient;
private final com.stytch.java.http.HttpClient fraudHttpClient;
Each HttpClient wraps an okhttp3.OkHttpClient, which owns a Dispatcher backed by an ExecutorService plus a ConnectionPool with idle-eviction threads. The coroutineScope is created from a SupervisorJob and never cancelled.
Because StytchClient doesn't implement Closeable / AutoCloseable and none of the internal fields are exposed, callers can't release any of it.
Why it matters
Tests. A test that constructs a real StytchClient (rather than a mock) leaks an OkHttpClient per test method. Across a suite the dispatcher threads pile up until OkHttp's idle eviction runs.
Per-tenant clients. Multi-tenant servers that scope a StytchClient per tenant keep every retired tenant's clients alive.
Graceful shutdown. Frameworks with structured shutdown can't release the SDK's resources before the rest of the application has stopped, which is awkward when ordering matters.
Activity
logan-stytch commentedon Apr 27, 2026
Hey @hudson155, thanks for the report. I just merged #149 which should address this and go out in v11.1.0