{
  "schema_version": 2,
  "id": "develop/clients/jedis/produsage",
  "title": "Production usage",
  "url": "https://redis.io/docs/latest/develop/clients/jedis/produsage/",
  "summary": "Get your Jedis app ready for production",
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc",
    "oss",
    "kubernetes",
    "clients"
  ],
  "last_updated": "2026-09-08T15:41:24+01:00",
  "page_type": "content",
  "content_hash": "2636f2e2f2f4e5ff18b9eb692115151f1d43458d7ac0cb263888aec6d1e37938",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "This guide offers recommendations to get the best reliability and\nperformance in your production environment."
    },
    {
      "id": "checklist",
      "title": "Checklist",
      "role": "content",
      "text": "Each item in the checklist below links to the section\nfor a recommendation. Use the checklist icons to record your\nprogress in implementing the recommendations.\n\n[code example]"
    },
    {
      "id": "recommendations",
      "title": "Recommendations",
      "role": "content",
      "text": "The sections below offer recommendations for your production environment. Some\nof them may not apply to your particular use case."
    },
    {
      "id": "connection-pooling",
      "title": "Connection pooling",
      "role": "content",
      "text": "Example code often opens a connection at the start, demonstrates a feature,\nand then closes the connection at the end. However, production code\ntypically uses connections many times intermittently. Repeatedly opening\nand closing connections has a performance overhead.\n\nUse [connection pooling](https://redis.io/docs/latest/develop/clients/pools-and-muxing)\nto avoid the overhead of opening and closing connections without having to\nwrite your own code to cache and reuse open connections. See\n[Configure a connection pool](https://redis.io/docs/latest/develop/clients/jedis/connect#configure-a-connection-pool)\nto learn how to use this technique with Jedis."
    },
    {
      "id": "connection-retries",
      "title": "Connection retries",
      "role": "content",
      "text": "If a connection is lost before a command is completed, the command will fail with a `JedisConnectionException`. However, a connection error is often transient, in which case the\ncommand will succeed after one or more reconnection attempts. See\n[Retrying a command after a connection failure](https://redis.io/docs/latest/develop/clients/jedis/connect#retrying-a-command-after-a-connection-failure)\nfor an example of a simple retry loop that can recover from a transient connection error."
    },
    {
      "id": "client-side-caching",
      "title": "Client-side caching",
      "role": "content",
      "text": "[Client-side caching](https://redis.io/docs/latest/develop/clients/client-side-caching)\ninvolves storing the results from read-only commands in a local cache. If the\nsame command is executed again later, the results can be obtained from the cache,\nwithout contacting the server. This improves command execution time on the client,\nwhile also reducing network traffic and server load. See\n[Connect using client-side caching](https://redis.io/docs/latest/develop/clients/jedis/connect#connect-using-client-side-caching)\nfor more information and example code."
    },
    {
      "id": "timeouts",
      "title": "Timeouts",
      "role": "content",
      "text": "If a network or server error occurs while your code is opening a\nconnection or issuing a command, it can end up hanging indefinitely.\nYou can prevent this from happening by setting timeouts for socket\nreads and writes and for opening connections.\n\nTo set a timeout for a connection, use `JedisClientConfig` with the `socketTimeout` and `connectionTimeout` parameters.\n(The socket timeout is the maximum time allowed for reading or writing data while executing a\ncommand. The connection timeout is the maximum time allowed for establishing a new connection.)\n\n[code example]"
    },
    {
      "id": "health-checks",
      "title": "Health checks",
      "role": "content",
      "text": "If your code doesn't access the Redis server continuously then it\nmight be useful to make a \"health check\" periodically (perhaps once\nevery few seconds). You can do this using a simple\n[`PING`](https://redis.io/docs/latest/commands/ping) command:\n\n[code example]\n\nHealth checks help to detect problems as soon as possible without\nwaiting for a user to report them."
    },
    {
      "id": "exception-handling",
      "title": "Exception handling",
      "role": "errors",
      "text": "Redis handles many errors using return values from commands, but there\nare also situations where exceptions can be thrown. In production code,\nyou should handle exceptions as they occur.\n\nThe Jedis exception hierarchy is rooted on `JedisException`, which implements\n`RuntimeException`. All exceptions in the hierarchy are therefore unchecked\nexceptions.\n\n[code example]\n\n#### General exceptions\n\nIn general, Jedis can throw the following exceptions while executing commands:\n\n- `JedisConnectionException` - when the connection to Redis is lost or closed unexpectedly. Configure failover to handle this exception automatically with Resilience4J and the built-in Jedis failover mechanism.  \n- `JedisAccessControlException` - when the user does not have the permission to execute the command or the user ID and/or password are incorrect.\n- `JedisDataException` - when there is a problem with the data being sent to or received from the Redis server. Usually, the error message will contain more information about the failed command.\n- `JedisException` - this exception is a catch-all exception that can be thrown for any other unexpected errors.\n\nConditions when `JedisException` can be thrown:\n- Bad return from a health check with the [`PING`](https://redis.io/docs/latest/commands/ping) command\n- Failure during SHUTDOWN\n- Pub/Sub failure when issuing commands (disconnect)\n- Any unknown server messages\n- Sentinel: can connect to sentinel but master is not monitored or all Sentinels are down.\n- MULTI or DISCARD command failed \n- Shard commands key hash check failed or no Reachable Shards\n- Retry deadline exceeded/number of attempts (Retry Command Executor)\n- POOL - pool exhausted, error adding idle objects, returning broken resources to the pool\n\nAll the Jedis exceptions are runtime exceptions and in most cases irrecoverable, so in general bubble up to the API capturing the error message."
    },
    {
      "id": "dns-cache-and-redis",
      "title": "DNS cache and Redis",
      "role": "content",
      "text": "When you connect to a Redis server with multiple endpoints, such as [Redis Software Active-Active](https://redis.com/redis-enterprise/technology/active-active-geo-distribution/), you *must*\ndisable the JVM's DNS cache. If a server node or proxy fails, the IP address for any database\naffected by the failure will change. When this happens, your app will keep\ntrying to use the stale IP address if DNS caching is enabled.\n\nUse the following code to disable the DNS cache:\n\n[code example]"
    }
  ],
  "examples": [
    {
      "id": "checklist-ex0",
      "language": "checklist {id=\"jedisprodlist\"}",
      "code": "- [ ] [Connection pooling](#connection-pooling)\n- [ ] [Connection retries](#connection-retries)\n- [ ] [Client-side caching](#client-side-caching)\n- [ ] [Timeouts](#timeouts)\n- [ ] [Health checks](#health-checks)\n- [ ] [Exception handling](#exception-handling)\n- [ ] [DNS cache and Redis](#dns-cache-and-redis)",
      "section_id": "checklist"
    },
    {
      "id": "timeouts-ex0",
      "language": "java",
      "code": "RedisClient jedisWithTimeout = RedisClient.builder()\n    .hostAndPort(\"localhost\", 6379)\n    .clientConfig(\n        DefaultJedisClientConfig.builder()\n            .socketTimeoutMillis(5000)  // set timeout to 5 seconds\n            .connectionTimeoutMillis(5000) // set connection timeout to 5 seconds\n            .build())\n    .build();",
      "section_id": "timeouts"
    },
    {
      "id": "health-checks-ex0",
      "language": "java",
      "code": "ConnectionPoolConfig poolConfig = new ConnectionPoolConfig();\npoolConfig.setMaxTotal(8);\npoolConfig.setMaxIdle(8);\npoolConfig.setMinIdle(0);\npoolConfig.setBlockWhenExhausted(true);\npoolConfig.setMaxWait(Duration.ofSeconds(1));\n\n// Enables sending a PING command once every second while the connection is idle.\npoolConfig.setTestWhileIdle(true);\npoolConfig.setTimeBetweenEvictionRuns(Duration.ofSeconds(1));\n\nRedisClient jedis = RedisClient.builder()\n        .hostAndPort(\"localhost\", 6379)\n        .poolConfig(poolConfig)\n        .build();",
      "section_id": "health-checks"
    },
    {
      "id": "exception-handling-ex0",
      "language": "hierarchy {type=\"exception\"}",
      "code": "\"JedisException\":\n    _meta:\n        description: \"Base class for all Jedis exceptions\"\n    \"JedisDataException\":\n        \"JedisRedirectionException\":\n            \"JedisMovedDataException\":\n            \"JedisAskDataException\":\n        \"AbortedTransactionException\":\n        \"JedisAccessControlException\":\n        \"JedisNoScriptException\":\n    \"JedisClusterException\":\n        \"JedisClusterOperationException\":\n        \"JedisConnectionException\":\n        \"JedisValidationException\":\n    \"InvalidURIException\":",
      "section_id": "exception-handling"
    },
    {
      "id": "dns-cache-and-redis-ex0",
      "language": "java",
      "code": "java.security.Security.setProperty(\"networkaddress.cache.ttl\",\"0\");\njava.security.Security.setProperty(\"networkaddress.cache.negative.ttl\", \"0\");",
      "section_id": "dns-cache-and-redis"
    }
  ]
}
