Performance & Monitoring¶
Startup speed¶
The system connects to PostgreSQL directly at server startup; the data is pre-loaded, so no ETL runs on each boot.
- First deployment: terminology data must first be imported through the admin console (Admin → Modules) — roughly 1 minute for ICD, 5–15 minutes for SNOMED CT.
- Subsequent starts: the service connects straight to PostgreSQL and starts within seconds.
- Initialisation model: the Node server creates the connection pool, Redis, and each service exactly once at process start (
main()innode-server/src/server.ts); each MCP session holds its own transport but shares these process-level singletons. (The old PythonmcpSDK's lifespan-per-session problem no longer exists.)
Recommendation: keep the PostgreSQL data volume persistent (already configured by default in compose.yaml) so loaded terminology data survives restarts.
Query performance¶
- pgBouncer connection pool: transaction mode, mapping 500 client connections onto 30 PG connections, supporting high concurrency.
- Redis cache:
cached()wraps common queries with a TTL-based cache (node-server/src/cache.ts), failing open on cache errors (the query runs against the DB, so availability is unaffected). - FTS indexes: every major search column has a PostgreSQL full-text search index.
pgdriver: uses unnamed prepared statements for compatibility with pgBouncer transaction mode.
Handling concurrency¶
The MCP server is implemented in Node.js (Express + @modelcontextprotocol/sdk). For high request volumes:
- Tune pgBouncer's
MAX_CLIENT_CONN(500 by default) andDEFAULT_POOL_SIZE(30 by default). - Monitor the Redis cache hit rate through Prometheus (
mcp_cache_operations_total). - Multiple container instances can share one PostgreSQL and one Redis.
Background jobs¶
ADMIN_MAX_CONCURRENT_JOBSbounds how many jobsadmin-workerruns at once (4 by default in compose); per-module resource slots additionally prevent parallel imports of the same module.- The worker's
NODE_OPTIONS=--max-old-space-size=8192is necessary: IG imports load whole dependency packages (such ashl7.fhir.r4.examples) into memory. Do not lower it.
Monitoring¶
The Prometheus metrics endpoint is on METRICS_PORT (9090 by default, bound to 127.0.0.1 only).