Connecting

Node.js

On each connection, the first command sent to the server must authenticate by issuing a set with username password as the value. The proxy responds STORED on success or CLIENT_ERROR invalid credentials on failure. The key name (shown here as _auth) is ignored by the proxy — any value works. This is the default Memcached authentication mechanism and does not require SASL support, which not every client or hosting environment has properly compiled in.

Use mc1.public.gra1.ovh.velstash.io to connect to your instance. We recommend using TLS (port 11212) for connections over the public Internet, since traffic between you and this region (cached values as well as credentials) may be easier to intercept if travelling unencrypted. We reserve the right to introduce usage-based pricing for disproportionate external traffic in the future, with advance notice.

Placeholders — replace with your instance's actual values: host mc1.public.gra1.ovh.velstash.io, username your-username, password your-password.

Installing a client

The memcached package may be used for plain TCP connections and for connecting using TLS through a local relay (shown as TLS Option B below). Alternatively, the memcache-client package can be used instead, which has native TLS support (shown as TLS Option A below).

npm install memcached

# only if you're using TLS Option A below
npm install memcache-client

Plain TCP

// Use the 'memcached' package (text protocol). memjs is binary-only and won't work.
const Memcached = require('memcached');

const client = new Memcached('mc1.public.gra1.ovh.velstash.io:11211');
client.set('_auth', 'your-username your-password', 0, (err) => {
  if (err) throw new Error('auth error');
});

TLS — Option A: memcache-client

The memcache-client package has native TLS support.

const { MemcacheClient } = require('memcache-client');

const client = new MemcacheClient({
  server: 'mc1.public.gra1.ovh.velstash.io:11212',
  tls: {
    servername: 'mc1.public.gra1.ovh.velstash.io',
  },
});

async function main() {
  await client.set('_auth', 'your-username your-password');
  await client.set('mykey', 'bar');
  const result = await client.get('mykey');
  console.log(result.value.toString());
  client.shutdown();
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});

TLS — Option B: memcached + local relay

If you'd rather keep using the memcached package, run a small local TLS relay in-process and point memcached at it over plain TCP on localhost:

const net = require('net');
const tls = require('tls');
const Memcached = require('memcached');

function startTlsRelay(localPort, remoteHost, remotePort, servername) {
  const server = net.createServer((localSocket) => {
    const remoteSocket = tls.connect(
      { host: remoteHost, port: remotePort, servername },
      () => {
        localSocket.pipe(remoteSocket);
        remoteSocket.pipe(localSocket);
      }
    );

    remoteSocket.on('error', () => localSocket.destroy());
    remoteSocket.on('close', () => localSocket.destroy());
    localSocket.on('error', () => remoteSocket.destroy());
    localSocket.on('close', () => remoteSocket.destroy());
  });

  server.listen(localPort, '127.0.0.1');
  return server;
}

startTlsRelay(
    21211,
    'mc1.public.gra1.ovh.velstash.io', 11212,
    'mc1.public.gra1.ovh.velstash.io'
);

const client = new Memcached('127.0.0.1:21211', {
  timeout: 2000,
  retries: 5,
  retry: 1000,
  reconnect: 5000,
});

client.set('_auth', 'your-username your-password', 0, (err) => {
  if (err) throw err;
  client.set('mykey', 'bar', 0, (err) => {
    if (err) throw err;
    client.get('mykey', (err, data) => {
      if (err) throw err;
      console.log(data);
    });
  });
});

Reading and writing

Shown here with the memcached package:

client.set('user:123:profile', JSON.stringify(data), 3600, (err) => { // 3600s TTL
  if (err) throw err;
});

client.get('user:123:profile', (err, data) => {
  if (err) throw err;
  if (data === undefined) {
    // cache miss
  }
});

Common pitfalls

  • Items over 1MB (the default max item size) fail silently on set — check the result code or error your client returns if a value doesn't seem to be sticking.
  • Prefixing keys with : (e.g. user:123:profile) is what makes the dashboard's top-keys/prefixes view group things meaningfully — worth doing from day one.
  • The auth set authenticates the underlying TCP connection, not the client object — it only needs to run once per connection (that's why each example above issues it right after connecting, not before every request). If your client library pools connections or silently reopens them, make sure new connections authenticate too before you rely on them.