Momento is a serverless caching platform that eliminates the operational burden of running Redis or Memcached clusters — no provisioning, no scaling decisions, just a cache API that scales automatically. But "serverless" does not mean "worry-free." Momento operations can fail when API rate limits are hit, when your application's authentication tokens expire, when network paths between your compute and Momento's endpoints degrade, or when cache-aside logic silently falls back to the database without anyone noticing. When Momento goes down or slows down, your application suddenly bears full database load.
Vigilmon gives you external visibility into Momento cache availability through HTTP probe monitoring and heartbeat monitoring for Momento-dependent workers. This tutorial covers both.
Why Momento Monitoring Matters
Momento's service dashboard shows aggregate availability. It cannot tell you:
- Whether Momento is reachable from your specific compute region — latency varies by region pair
- Whether your API tokens have expired and cache operations are silently failing with auth errors
- Whether your app has hit Momento's request rate limits and is transparently falling back to the database
- Whether cache-aside logic in your code is mishandling Momento errors and bypassing the cache entirely
- Whether your Momento-dependent background processes have silently stopped warming or invalidating cache
These failures appear as "database overload" rather than "cache failure," making them easy to misdiagnose. External monitoring through Vigilmon validates the actual cache path your application uses.
Step 1: Build a Momento Health Endpoint
Create a thin health endpoint that performs a Momento set/get round-trip and returns HTTP 200 or 503. This tests authentication, network connectivity, and basic cache operations together.
Node.js Example (Express)
// momento-health.js
const express = require('express');
const { CacheClient, Configurations, CredentialProvider, CacheGet, CacheSet } = require('@gomomento/sdk');
const app = express();
const client = new CacheClient({
configuration: Configurations.Laptop.latest(),
credentialProvider: CredentialProvider.fromEnvironmentVariable('MOMENTO_API_KEY'),
defaultTtlSeconds: 60,
});
const CACHE_NAME = process.env.MOMENTO_CACHE_NAME || 'healthcheck';
app.get('/health/momento', async (req, res) => {
const start = Date.now();
const key = '_vigilmon_healthcheck';
const value = start.toString();
try {
// Write
const setResp = await client.set(CACHE_NAME, key, value);
if (setResp instanceof CacheSet.Error) {
return res.status(503).json({
status: 'down',
phase: 'write',
error: setResp.errorCode(),
});
}
// Read back
const getResp = await client.get(CACHE_NAME, key);
if (getResp instanceof CacheGet.Miss) {
return res.status(503).json({ status: 'degraded', reason: 'read_miss_after_write' });
}
if (getResp instanceof CacheGet.Error) {
return res.status(503).json({
status: 'down',
phase: 'read',
error: getResp.errorCode(),
});
}
return res.status(200).json({
status: 'ok',
latency_ms: Date.now() - start,
});
} catch (err) {
return res.status(503).json({ status: 'down', error: err.message });
}
});
app.listen(3001);
Python Example (FastAPI)
# momento_health.py
import os, time
from momento import CacheClient, Configurations, CredentialProvider
from momento.responses import CacheGet, CacheSet
from fastapi import FastAPI
from fastapi.responses import JSONResponse
app = FastAPI()
cache_client = CacheClient(
configuration=Configurations.Laptop.latest(),
credential_provider=CredentialProvider.from_environment_variable('MOMENTO_API_KEY'),
default_ttl_seconds=60,
)
CACHE_NAME = os.environ.get('MOMENTO_CACHE_NAME', 'healthcheck')
@app.get('/health/momento')
def momento_health():
start = int(time.time() * 1000)
key = '_vigilmon_healthcheck'
value = str(start)
try:
set_resp = cache_client.set(CACHE_NAME, key, value)
if isinstance(set_resp, CacheSet.Error):
return JSONResponse(status_code=503, content={
'status': 'down',
'phase': 'write',
'error': str(set_resp),
})
get_resp = cache_client.get(CACHE_NAME, key)
if isinstance(get_resp, CacheGet.Miss):
return JSONResponse(status_code=503, content={
'status': 'degraded',
'reason': 'read_miss_after_write',
})
if isinstance(get_resp, CacheGet.Error):
return JSONResponse(status_code=503, content={
'status': 'down',
'phase': 'read',
'error': str(get_resp),
})
return {'status': 'ok', 'latency_ms': int(time.time() * 1000) - start}
except Exception as e:
return JSONResponse(status_code=503, content={
'status': 'down',
'error': str(e),
})
Verify it manually before adding to Vigilmon:
curl -i https://your-app.example.com/health/momento
# HTTP/1.1 200 OK
# {"status":"ok","latency_ms":18}
Step 2: Configure a Vigilmon HTTP Monitor
- Log in to vigilmon.online and go to Monitors → New Monitor
- Choose HTTP / HTTPS
- Set the URL to your Momento health endpoint:
https://your-app.example.com/health/momento - Set the check interval to 1 minute
- Under Expected response, configure:
- Status code:
200 - Response body contains:
"status":"ok" - Response time threshold:
500ms(Momento is fast; a slow health response is an early warning)
- Status code:
- Under Alert channels, assign your Slack or email channel
- Save the monitor
Vigilmon probes from multiple geographic regions simultaneously and requires multi-region consensus before opening an incident — so a transient single-probe blip will not page you.
What This Catches
| Failure | Momento Dashboard | Vigilmon | |---|---|---| | Momento regional outage | ✓ | ✓ | | API token expiry | ✗ | ✓ | | Network path degradation from your compute | ✗ | ✓ | | Cache-aside logic silently bypassing Momento | ✗ | ✓ | | Rate limit exhaustion causing errors | ✗ | ✓ |
Step 3: Heartbeat Monitoring for Cache Warming Workers
If you run background workers that warm or pre-populate the Momento cache, those workers will silently stop when Momento is unavailable or when authentication tokens expire. The cache goes cold, and your database absorbs the traffic surge when the next deployment or cold start hits.
Vigilmon heartbeat monitors detect silent worker death: your worker pings Vigilmon after each successful cache warming cycle. If the ping stops, Vigilmon opens an incident.
Set Up the Heartbeat Monitor
- In Vigilmon, go to Monitors → New Monitor → Heartbeat
- Name it:
momento-cache-warmer - Set the expected interval: 15 minutes (adjust to your warming frequency)
- Set the grace period: 30 minutes
- Save — copy the heartbeat URL
Wire Into Your Cache Warmer
const axios = require('axios');
const { CacheClient, Configurations, CredentialProvider } = require('@gomomento/sdk');
const client = new CacheClient({
configuration: Configurations.Laptop.latest(),
credentialProvider: CredentialProvider.fromEnvironmentVariable('MOMENTO_API_KEY'),
defaultTtlSeconds: 3600,
});
async function warmCache() {
const items = await fetchPopularItems();
for (const item of items) {
await client.set('app-cache', `item:${item.id}`, JSON.stringify(item));
}
// Heartbeat: ping Vigilmon after successful warming cycle
await axios.get(process.env.VIGILMON_HEARTBEAT_URL).catch(() => {});
}
// Run every 15 minutes
setInterval(warmCache, 15 * 60 * 1000);
warmCache();
Step 4: Monitor Token Expiry Proactively
Momento API tokens have a configurable TTL. When a token expires, all cache operations fail with an authentication error, but your application may silently fall back to the database without any visible error. Build token expiry awareness into your health endpoint:
app.get('/health/momento/token', async (req, res) => {
// Decode the JWT to check expiry without a network call
const token = process.env.MOMENTO_API_KEY;
try {
const payload = JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
const expiresAt = payload.exp * 1000;
const msUntilExpiry = expiresAt - Date.now();
if (msUntilExpiry < 24 * 60 * 60 * 1000) {
return res.status(503).json({
status: 'warning',
reason: 'token_expires_soon',
expires_in_hours: Math.floor(msUntilExpiry / 3600000),
});
}
return res.status(200).json({ status: 'ok', expires_in_hours: Math.floor(msUntilExpiry / 3600000) });
} catch (err) {
return res.status(503).json({ status: 'down', error: 'invalid_token' });
}
});
Add this as a separate Vigilmon monitor with a 24-hour check interval and a Slack-only alert channel. This gives you advance warning before tokens expire without paging on-call.
Step 5: Alerting Best Practices for Momento
Momento failures follow a predictable impact chain: cache unavailable → application falls back to database → database CPU spikes → application latency rises → user-facing errors. Alert before the cascade completes.
Configure alert channels by monitor:
- Momento health endpoint → Slack + PagerDuty (P1 — cache is down, database is absorbing full load)
- Cache warming heartbeat → Slack + email (P2 — cache will go cold on next deployment)
- Token expiry monitor → Slack only (P3 — advance warning, no immediate user impact)
- Response time alert at 200ms → Slack only (early warning for Momento API latency)
Summary
Momento's serverless model makes it easy to start, but silent failure modes (auth expiry, rate limits, cache-aside bugs) require external monitoring to catch. Vigilmon gives you full visibility:
| Monitor Type | What It Covers |
|---|---|
| HTTP monitor on /health/momento | Set/get availability, auth, network path |
| HTTP monitor on /health/momento/token | API token expiry early warning |
| Heartbeat monitor | Cache warming worker liveness |
Get started free at vigilmon.online — your first Momento monitor is running in under two minutes.