Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/upstash/redis-js/llms.txt

Use this file to discover all available pages before exploring further.

Description

Decrements the number stored at key by one. If the key does not exist, it is set to 0 before performing the operation. An error is returned if the key contains a value of the wrong type or contains a string that cannot be represented as an integer.

Syntax

redis.decr(key: string): Promise<number>

Parameters

key
string
required
The key containing the integer to decrement

Returns

value
number
The value of the key after the decrement

Examples

Basic Usage

import { Redis } from '@upstash/redis';

const redis = new Redis({
  url: 'https://your-redis-url.upstash.io',
  token: 'your-token'
});

// Set an initial value
await redis.set('counter', 10);

// Decrement by 1
const newValue = await redis.decr('counter');
console.log(newValue); // 9

const value = await redis.get('counter');
console.log(value); // "9"

Decrement Non-Existent Key

// Decrementing a non-existent key initializes it to 0 and then decrements
const result = await redis.decr('newcounter');
console.log(result); // -1

Multiple Decrements

await redis.set('inventory', 100);

// Decrement multiple times
await redis.decr('inventory'); // 99
await redis.decr('inventory'); // 98
await redis.decr('inventory'); // 97

const remaining = await redis.get('inventory');
console.log(remaining); // "97"

Inventory Management

// Track product inventory
async function sellProduct(productId: string, quantity: number = 1) {
  for (let i = 0; i < quantity; i++) {
    const remaining = await redis.decr(`product:${productId}:stock`);
    if (remaining < 0) {
      // Rollback - increment back
      await redis.incr(`product:${productId}:stock`);
      throw new Error('Out of stock');
    }
  }
}

// Initialize stock
await redis.set('product:123:stock', 5);

// Sell 2 items
await sellProduct('123', 2);
const stock = await redis.get('product:123:stock');
console.log(stock); // "3"

Countdown Timer

// Set up a countdown
await redis.set('countdown', 10);

const interval = setInterval(async () => {
  const remaining = await redis.decr('countdown');
  console.log(`${remaining} seconds remaining`);
  
  if (remaining <= 0) {
    clearInterval(interval);
    console.log('Countdown complete!');
  }
}, 1000);

Rate Limiting (Remaining Credits)

// Initialize user credits
await redis.set('user:123:credits', 100);

async function useCredit(userId: string): Promise<number> {
  const remaining = await redis.decr(`user:${userId}:credits`);
  
  if (remaining < 0) {
    // Rollback and throw error
    await redis.incr(`user:${userId}:credits`);
    throw new Error('Insufficient credits');
  }
  
  return remaining;
}

try {
  const credits = await useCredit('123');
  console.log(`${credits} credits remaining`);
} catch (error) {
  console.error(error.message);
}

Download Counter

// Track remaining downloads
async function trackDownload(fileId: string) {
  const remaining = await redis.decr(`file:${fileId}:downloads:remaining`);
  
  if (remaining < 0) {
    await redis.incr(`file:${fileId}:downloads:remaining`);
    return { allowed: false, remaining: 0 };
  }
  
  return { allowed: true, remaining };
}

// Set initial download limit
await redis.set('file:abc:downloads:remaining', 3);

const result1 = await trackDownload('abc');
console.log(result1); // { allowed: true, remaining: 2 }

const result2 = await trackDownload('abc');
console.log(result2); // { allowed: true, remaining: 1 }

Seat Reservation System

// Initialize available seats
await redis.set('event:concert:seats', 100);

async function reserveSeat(eventId: string): Promise<{ success: boolean; seatsLeft: number }> {
  const seatsLeft = await redis.decr(`event:${eventId}:seats`);
  
  if (seatsLeft < 0) {
    // No seats available, rollback
    await redis.incr(`event:${eventId}:seats`);
    return { success: false, seatsLeft: 0 };
  }
  
  return { success: true, seatsLeft };
}

const reservation = await reserveSeat('concert');
if (reservation.success) {
  console.log(`Seat reserved! ${reservation.seatsLeft} seats remaining`);
} else {
  console.log('Sorry, event is sold out');
}

Notes

  • This is an atomic operation, making it safe for concurrent decrements
  • The value must be an integer or a string that can be parsed as an integer
  • If the key contains a non-integer value, an error will be returned
  • The operation has O(1) time complexity
  • The range of values is limited to 64-bit signed integers
  • Decrementing below zero is allowed (will result in negative numbers)

Error Handling

try {
  // This will throw an error because "hello" is not a valid integer
  await redis.set('mykey', 'hello');
  await redis.decr('mykey');
} catch (error) {
  console.error('Cannot decrement non-integer value');
}
  • incr - Increment the integer value of a key by one

Redis Documentation

For more information, see the Redis DECR documentation.