Bex Key Value is a managed Valkey store compatible with Redis clients. Use it for caches, shared coordination, or a job queue supported by your application. It is a separate resource, so several services can share it without tying its lifecycle to a single application deployment.
Choose eviction and persistence settings according to the data's role. A cache that can discard old entries and a queue that must retain pending work should not automatically use the same policy.
Create a store and connect a service
A render.yaml Blueprint can declare the store and its
consumer together:
services:
- name: cache
type: keyvalue
plan: free
ipAllowList: []
- name: web
type: web
runtime: docker
repo: https://github.com/your-org/web
envVars:
- key: REDIS_URL
fromService:
name: cache
type: keyvalue
property: connectionStringReplace the application repository, choose appropriate plans, then validate
and apply the Blueprint. Your application reads REDIS_URL. The supported
reference is fromService with type: keyvalue, not fromKeyValue.
A Key Value declaration needs no language runtime or application Dockerfile.
For an explicitly private store through REST, set the API origin and an authorized workspace token:
curl --fail-with-body -X POST "$BEX_API_URL/v1/key-value" \
-H "Authorization: Bearer $BEX_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"cache","plan":"free","public":false}'In this REST endpoint, omitting public enables public access when a nonempty
IP allowlist is supplied; otherwise it stays private. Specify the intended
access and inspect the created store. External routing also requires the
instance's Key Value domain and gateway configuration.
Retrieve the correct connection string
Use the dashboard's connection details, or set KEY_VALUE_ID to the returned
resource id:
curl --fail-with-body "$BEX_API_URL/v1/key-value/$KEY_VALUE_ID/connection-info" \
-H "Authorization: Bearer $BEX_TOKEN"The response includes internalConnectionString, an external string when
available, and cliCommand. It contains credentials and requires sensitive-value
access. Keep it out of source control and public logs.
Use the returned internal redis:// connection string from an allowed Bex
service. Use the returned external rediss:// URL from an external client when
public routing is ready. The external CLI command includes --sni with the
actual host; this matters because the gateway routes by TLS server name.
Do not reconstruct that hostname from the display name or replace it with an IP.
After securely setting REDIS_URL to the internal connection string, test from
an allowed peer service:
redis-cli -u "$REDIS_URL" PINGA healthy authenticated connection returns PONG. For an external client,
use the returned command's TLS/SNI settings and the appropriate certificate
trust configuration. Internal redis:// transport is not encrypted simply
because it is on a private network.
Choose an eviction policy
When memory reaches its configured limit, maxmemoryPolicy decides whether
and how Valkey discards keys. Examples include:
| REST setting | Behavior |
|---|---|
allkeys_lru | Evicts less recently used keys across the store; useful for disposable caches. |
allkeys_lfu | Evicts less frequently used keys across the store. |
volatile_lru | Selects eviction candidates among keys with an expiry. |
noeviction | Refuses memory-growing writes instead of discarding keys when full. |
For queues, follow the queue library's requirements and monitor write failures;
noeviction avoids eviction but does not create unlimited capacity. Review the
policy before changing a live store:
curl --fail-with-body -X PATCH "$BEX_API_URL/v1/key-value/$KEY_VALUE_ID" \
-H "Authorization: Bearer $BEX_TOKEN" \
-H "Content-Type: application/json" \
-d '{"maxmemoryPolicy":"noeviction"}'The API's canonical enum spelling uses underscores; Kubernetes/Valkey settings use hyphens. The currently supported policies are validated by Bex rather than passed through as arbitrary Valkey configuration.
Persistence is separate from backups
The REST persistenceMode values are:
| Value | Storage behavior |
|---|---|
journal_snapshot | Append-only journaling plus snapshot behavior. |
snapshot | Snapshot persistence without append-only journaling. |
off | In-memory operation without AOF or scheduled RDB persistence. |
Bex maps these onto Valkey configuration. Changing mode is an operational change that should be reviewed against your application's data-loss tolerance; it is not an immediate backup or a guarantee that every acknowledged write survives every failure.
Backup creation additionally depends on the plan and instance's backup-store configuration. Confirm that backups are actually completing with your instance operator before relying on recovery. The current public Key Value REST surface does not provide a tenant snapshot-list/restore workflow; do not reuse service-disk snapshot endpoints or assume Render's recovery behavior applies.
Self-hosted operators who need an isolated RDB restore drill should follow Recovery: Key Value after Platform recovery preparation.
Access, storage, and lifecycle
External IP rules apply to the public endpoint. Internal access still depends on workspace/environment network policy and valid credentials. Adding a DNS record alone does not enable a datastore gateway.
Storage is grow-only: a compute-plan downgrade does not shrink an existing volume. Monitor memory, evictions, connection counts, and latency alongside storage usage. Restart interrupts connections; suspension makes the store unavailable until resumed. Configure clients to reconnect appropriately. Deleting the store removes its data; preserve anything you need first.
Troubleshoot
For authentication failures, retrieve fresh authorized connection details and check whether credential changes are still converging. For external failures, check public access, allowlist, DNS, TLS trust, and SNI. For rejected writes, inspect memory limits and eviction policy. For missing keys, distinguish expiration, eviction, application deletion, and a persistence failure.
See Private network, Secrets, PostgreSQL, and Persistent disks.