Skip to content

Memcached - Replace Data

The Memcached replace command updates the value of an existing key. Its key characteristic is that it will only succeed if the key already exists in the cache. This makes it a safer alternative to set when your intention is strictly to update, not create.

The basic syntax for the replace command is:

replace key flags exptime bytes [noreply]
value

The parameters are identical to the set command. key is the target key, exptime is the new expiration time, and value is the new data.

  • STORED indicates the value was successfully replaced.
  • NOT_STORED indicates that the operation failed because the key does not exist.
  • ERROR indicates a syntax error.

This example shows that replace fails on a non-existent key, but succeeds after an initial value is set using the add command.

# 1. Attempt to replace a key that doesn't exist.
replace config:feature_flag 0 900 4
true
NOT_STORED
# 2. Add an initial value for the key. 'add' only succeeds if the key does NOT exist.
add config:feature_flag 0 900 5
false
STORED
# 3. Retrieve the initial value.
get config:feature_flag
VALUE config:feature_flag 0 5
false
END
# 4. Now, replace the existing key's value.
replace config:feature_flag 0 900 4
true
STORED
# 5. Verify the new value.
get config:feature_flag
VALUE config:feature_flag 0 4
true
END

Modern Application: Replacing Data with Python

Section titled “Modern Application: Replacing Data with Python”

Here is a practical example of using replace in a Python application with the pymemcache library.

Ensure pymemcache is installed:

pip install pymemcache
from pymemcache.client.base import Client
MEMCACHED_SERVER = ('127.0.0.1', 11211)
def run_replace_example():
"""Demonstrates the replace operation's behavior."""
client = Client(MEMCACHED_SERVER)
key = 'user:session:abc-123'
# Ensure we have a clean slate
client.delete(key)
try:
# 1. Attempt to replace a non-existent key
# The replace method returns True on success, False otherwise.
was_replaced = client.replace(key, '{"status": "active"}', expire=3600)
print(f"-> REPLACE on non-existent key '{key}'... Success: {was_replaced}")
# 2. Set an initial value
client.set(key, '{"status": "pending"}', expire=3600)
initial_value = client.get(key).decode('utf-8')
print(f"-> SET: Initialized key '{key}' with value: {initial_value}")
# 3. Now, replace the existing value
new_value = '{"status": "active", "last_seen": "2023-10-27T11:00:00Z"}'
was_replaced = client.replace(key, new_value, expire=3600)
print(f"-> REPLACE on existing key... Success: {was_replaced}")
# 4. Verify the new value
final_value = client.get(key).decode('utf-8')
print(f"-> GET: Final value is: {final_value}")
except Exception as e:
print(f"An unexpected error occurred: {e}")
finally:
client.close()
if __name__ == "__main__":
run_replace_example()
-> REPLACE on non-existent key 'user:session:abc-123'... Success: False
-> SET: Initialized key 'user:session:abc-123' with value: {"status": "pending"}
-> REPLACE on existing key... Success: True
-> GET: Final value is: {"status": "active", "last_seen": "2023-10-27T11:00:00Z"}

Best Practices and Real-World Applications

Section titled “Best Practices and Real-World Applications”
  • Intentional Updates: Use replace when your code’s logic assumes an item is already in the cache. This prevents accidentally creating a new cache entry if, for some reason (like expiration or eviction), it disappeared. This can help expose bugs or logic errors.
  • Session Management: A good use case is updating a user’s session data. When a user performs an action, you replace their session key with updated information (e.g., a new last_seen timestamp). If the session doesn’t exist (maybe they timed out), the replace will fail, and your application can correctly prompt them to log in again.
  • replace vs. set: Use set when you want to store a value regardless of whether it already exists (create or update). Use replace when you only want to update an existing value.
  • replace vs. cas: replace is simpler than cas. Use replace for simple, non-concurrent updates. Use cas when you need to perform a read-modify-write operation and must protect against race conditions.