{"id":20738810,"url":"https://github.com/ebean-orm/ebean-datasource","last_synced_at":"2026-06-13T01:01:13.609Z","repository":{"id":6037694,"uuid":"54543049","full_name":"ebean-orm/ebean-datasource","owner":"ebean-orm","description":"Implementation of datasource-api - a SQL DataSource implementation","archived":false,"fork":false,"pushed_at":"2026-06-10T04:51:04.000Z","size":601,"stargazers_count":9,"open_issues_count":4,"forks_count":4,"subscribers_count":4,"default_branch":"main","last_synced_at":"2026-06-10T06:29:38.244Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ebean-orm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2016-03-23T08:28:21.000Z","updated_at":"2026-06-10T04:51:08.000Z","dependencies_parsed_at":"2024-06-21T00:19:10.304Z","dependency_job_id":"9f6c10b4-495f-447e-8d09-83bd6401dfa4","html_url":"https://github.com/ebean-orm/ebean-datasource","commit_stats":null,"previous_names":["ebean-orm/avaje-datasource"],"tags_count":68,"template":false,"template_full_name":null,"purl":"pkg:github/ebean-orm/ebean-datasource","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ebean-orm%2Febean-datasource","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ebean-orm%2Febean-datasource/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ebean-orm%2Febean-datasource/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ebean-orm%2Febean-datasource/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ebean-orm","download_url":"https://codeload.github.com/ebean-orm/ebean-datasource/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ebean-orm%2Febean-datasource/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34268189,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-12T02:00:06.859Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-17T06:20:46.205Z","updated_at":"2026-06-13T01:01:13.603Z","avatar_url":"https://github.com/ebean-orm.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build](https://github.com/ebean-orm/ebean-datasource/actions/workflows/build.yml/badge.svg)](https://github.com/ebean-orm/ebean-datasource/actions/workflows/build.yml)\n[![Maven Central : ebean](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean-datasource/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean-datasource)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/ebean-orm/ebean-datasource/blob/main/LICENSE)\n[![JDK EA](https://github.com/ebean-orm/ebean-datasource/actions/workflows/jdk-ea.yml/badge.svg)](https://github.com/ebean-orm/ebean-datasource/actions/workflows/jdk-ea.yml)\n\n# ebean-datasource\nA robust and fast SQL DataSource implementation\n\n## Table of Contents\n\n- [Documentation \u0026 Guides](#documentation--guides)\n- [Example use](#example-use)\n- [Robust and fast](#robust-and-fast)\n- [Read-Only Connection Pools](#read-only-connection-pools)\n- [Kubernetes / Container Deployment](#kubernetes--container-deployment)\n- [AWS Lambda](#aws-lambda)\n- [Mature](#mature)\n- [Java modules use](#java-modules-use)\n\n### Documentation \u0026 Guides\n\nThis project includes step-by-step guides for common datasource configuration scenarios.\n\n**See [docs/guides/README.md](docs/guides/README.md)** for:\n- [Creating DataSource pools](docs/guides/create-datasource-pool.md) — basic pools, read-only pools, Kubernetes deployment, AWS Lambda, and configuration reference\n- [Connection Validation Best Practices](docs/guides/connection-validation-best-practices.md) — how to configure heartbeat validation and why explicit heartbeatSql is rarely needed\n- [Configuration Reference](docs/guides/configuration-reference.md) — every builder setting, its default, and the equivalent property key for external configuration\n- [Troubleshooting Connection Leaks \u0026 Pool Exhaustion](docs/guides/troubleshooting-connection-leaks.md) — diagnosing pool exhaustion, leaks, and common warnings\n- [Monitoring Pool Metrics](docs/guides/monitoring-pool-metrics.md) — reading PoolStatus metrics, pool state, and outage alerts\n- [AWS Aurora with dual DataSources](docs/guides/aws-aurora-read-write-split.md) — read-write endpoint separation with Ebean ORM integration\n- Instructions for AI agents to discover and follow these guides\n\nThese guides are designed for both developers and AI coding agents (Copilot, Claude, Cursor, etc.) to follow step-by-step instructions for common tasks.\n\n### Example use:\n\n```java\nDataSourcePool pool = DataSourcePool.builder()\n  .name(\"mypool\")\n  .url(\"jdbc:h2:mem:test\")\n  .username(\"sa\")\n  .password(\"\")\n  .build();\n```\n\nFor read-only use cases, configure the pool with `readOnly(true)` and `autoCommit(true)` for optimal performance:\n\n```java\nDataSourcePool readOnlyPool = DataSourcePool.builder()\n  .name(\"mypool-readonly\")\n  .url(\"jdbc:h2:mem:test\")\n  .username(\"sa\")\n  .password(\"\")\n  .readOnly(true)\n  .autoCommit(true)\n  .build();\n```\n\nUse like any java.sql.DataSource obtaining pooled connections\n```java\n    try (Connection connection = pool.getConnection()) {\n      try (PreparedStatement stmt = connection.prepareStatement(\"create table junk (acol varchar(10))\")) {\n        stmt.execute();\n        connection.commit();\n      }\n    }\n\n```\n\nFor CRaC beforeCheckpoint() we can take the pool offline\nclosing the connections and stopping heart beat checking\n```java\n// take it offline\npool.offline();\n```\n\nFor CRaC afterRestore() we can bring the pool online\ncreating the min number of connections and re-starting heart beat checking\n```java\npool.online();\n```\n\nFor explicit shutdown of the pool\n```java\npool.shutdown();\n```\n\n### Robust and fast\n\nThis pool is robust in terms of handling loss of connectivity to the database and restoring connectivity.\nIt will automatically reset itself as needed.\n\nThis pool is fast and simple. It uses a strategy of testing connections in the background and when connections\nare returned to the pool that have throw SQLException. This makes the connection testing strategy low overhead\nbut also robust.\n\n\n### Read-Only Connection Pools\n\nFor read-only use cases (analytics, reporting, caching, microservices that only query), create a\nseparate read-only pool configured with `readOnly(true)` and `autoCommit(true)`. This optimizes\nthe connection pool specifically for read-only workloads:\n\n```java\nDataSourcePool readOnlyPool = DataSourcePool.builder()\n  .name(\"mypool-readonly\")\n  .url(\"jdbc:postgresql://read-replica.example.com:5432/myapp\")\n  .username(\"readonly_user\")\n  .password(\"pass\")\n  .readOnly(true)\n  .autoCommit(true)\n  .minConnections(5)\n  .maxConnections(30)\n  .build();\n```\n\n**Benefits of read-only pools:**\n\n- **Database optimization:** Read-only mode signals the JDBC driver and database that no transactions\n  will be written. This allows the database to optimize query execution and skip transaction overhead.\n\n- **Reduced resource usage:** `autoCommit(true)` eliminates the overhead of managing explicit transaction\n  boundaries for each query. The database doesn't need to maintain transaction state for read-only operations.\n\n- **Lower latency:** Queries execute faster without transaction coordination overhead, improving response\n  times for read-heavy workloads.\n\n- **Separation of concerns:** Using a dedicated read-only pool makes the intent of your code clear and\n  allows you to configure connection pooling independently from your write pool.\n\n- **Better scaling:** Read-only pools can often use different connection sizing, timeouts, and validation\n  strategies optimized specifically for query operations.\n\n**Common read-only scenarios:**\n\n- Analytics and reporting engines querying large datasets\n- Microservices that only read from shared databases\n- Caching layers (e.g., warm-up queries for distributed caches)\n- Read replicas in multi-region deployments\n- Background workers that periodically fetch reference data\n\n\n### Kubernetes / Container Deployment\n\nWhen deploying to Kubernetes or other container orchestration platforms, configure `initialConnections`\nin addition to `minConnections` and `maxConnections`:\n\n```java\nDataSourcePool pool = DataSourcePool.builder()\n  .name(\"mypool\")\n  .url(\"jdbc:postgresql://db.example.com:5432/myapp\")\n  .username(\"user\")\n  .password(\"pass\")\n  .minConnections(5)\n  .initialConnections(20)      // Start with sufficient connections for production load\n  .maxConnections(50)           // Upper bound during peak usage\n  .build();\n```\n\n**Why this matters:**\n\n- **Rapid production readiness:** When a new pod is deployed, it immediately serves production traffic.\n  Setting `initialConnections` higher than `minConnections` (typically between min and max) ensures\n  the pod can handle incoming requests without the cold-start overhead of creating many connections.\n\n- **Automatic scaling down:** The pool continuously trims unused connections in the background\n  (default trim frequency is 59 seconds). Over time, the pool naturally shrinks back to a\n  sustainable size as demand normalizes, so you don't waste resources.\n\n- **Prevent connection storms:** Without adequate initial connections, new deployments spike\n  database load by creating many new connections simultaneously to service incoming requests.\n\n**Configuration strategies:**\n\n**Low-traffic services:**\n```java\n.minConnections(2)\n.initialConnections(5)\n.maxConnections(20)\n```\n\n**Medium-traffic services:**\n```java\n.minConnections(5)\n.initialConnections(20)\n.maxConnections(50)\n```\n\n**High-traffic services:**\n```java\n.minConnections(10)\n.initialConnections(40)\n.maxConnections(100)\n```\n\nStart with these values as a baseline and adjust based on your application's observed connection usage\nand deployment patterns. The pool will automatically trim idle connections over time, so starting with\nmore connections during deployment doesn't permanently increase resource consumption.\n\n\n### AWS Lambda\n\nThe connection pool has built-in support for AWS Lambda. When running in Lambda, the pool\n**automatically disables background thread validation** to optimize for cost and\nresource efficiency.\n\n**Automatic Detection:**\n\nThe pool detects Lambda environments by checking for the `LAMBDA_TASK_ROOT` environment variable (set by\nAWS Lambda runtime). When detected, `validateOnHeartbeat` is automatically set to `false`.\n\n**What Changes:**\n\n- **Background heartbeat thread is disabled:** Normally the pool validates connection health every 30 seconds\n  in the background. This thread is skipped in Lambda to avoid unnecessary CPU costs.\n\n- **Connection validation still works:** Dead or stale connections are still detected eagerly when they are\n  returned to the pool or when you attempt to use them. This ensures the pool remains robust.\n\n- **Why this matters:** Lambda functions are charged per millisecond of execution. Background threads consume\n  CPU time even when the function is idle, directly increasing your Lambda costs. Serverless functions are\n  ephemeral and short-lived, making background threads less useful anyway.\n\n**Configuration for Lambda:**\n\nKeep connection pools lean in Lambda since functions are short-lived and scale horizontally:\n\n```java\nDataSourcePool pool = DataSourcePool.builder()\n  .name(\"mypool\")\n  .url(\"jdbc:postgresql://db.example.com:5432/myapp\")\n  .username(\"user\")\n  .password(\"pass\")\n  .minConnections(1)           // Minimal baseline\n  .initialConnections(2)       // Only what's needed for one invocation\n  .maxConnections(10)          // Rarely needed; horizontal scaling handles load\n  .build();\n```\n\n\n\n**Important notes:**\n\n- Connection pooling in Lambda is **per-Lambda instance**, not per-invocation. A connection pool\n  persists across warm invocations of the same Lambda container.\n\n- Always minimize `minConnections` to reduce startup time and resource usage during cold starts.\n\n- The pool is still fully robust and reliable in Lambda despite the disabled background heartbeat.\n\n\n### Mature\n\nThis pool has been is heavy use for more that 16 years and stable since April 2010 (the last major refactor to use  `java.util.concurrent.locks`).\n\nThis pool was previously part of Ebean ORM with prior history in sourceforge.\n\nThere are other good DataSource pools out there but this pool has proven to be fast, simple and robust and maintains it's status as the preferred pool for use with Ebean ORM.\n\n\n### Java modules use\n\n```java\nmodule my.example {\n\n  requires io.ebean.datasource;\n  ...\n\n}\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Febean-orm%2Febean-datasource","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Febean-orm%2Febean-datasource","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Febean-orm%2Febean-datasource/lists"}