# Upstash Redis

Build an Edge Functions Counter with Upstash Redis.



A Redis counter example that stores a [hash](https://redis.io/commands/hincrby/) of function invocation count per region. Find the code on [GitHub](https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/upstash-redis-counter).

## Redis database setup

Create a Redis database using the [Upstash Console](https://console.upstash.com/) or [Upstash CLI](https://github.com/upstash/cli).

Select the `Global` type to minimize the latency from all edge locations. Copy the `UPSTASH_REDIS_REST_URL` and `UPSTASH_REDIS_REST_TOKEN` to your .env file.

You'll find them under **Details > REST API > .env**.

```bash
cp supabase/functions/upstash-redis-counter/.env.example supabase/functions/upstash-redis-counter/.env
```

## Code

Make sure you have the latest version of the [Supabase CLI installed](/docs/guides/local-development/cli/getting-started#installing-the-supabase-cli).

Create a new function in your project:

```bash
supabase functions new upstash-redis-counter
```

And add the code to the `index.ts` file:

```ts index.ts
import { withSupabase } from 'npm:@supabase/server@^1'
import { Redis } from 'npm:@upstash/redis@^1'

console.log(`Function "upstash-redis-counter" up and running!`)

// Open endpoint for testing. In production, implement an authorization layer in the handler or switch the auth mode.
export default {
  fetch: withSupabase({ auth: 'none' }, async (req, ctx) => {
    try {
      const redis = new Redis({
        url: Deno.env.get('UPSTASH_REDIS_REST_URL')!,
        token: Deno.env.get('UPSTASH_REDIS_REST_TOKEN')!,
      })

      const deno_region = Deno.env.get('DENO_REGION')
      if (deno_region) {
        // Increment region counter
        await redis.hincrby('supa-edge-counter', deno_region, 1)
      } else {
        // Increment localhost counter
        await redis.hincrby('supa-edge-counter', 'localhost', 1)
      }

      // Get all values
      const counterHash: Record<string, number> | null = await redis.hgetall('supa-edge-counter')
      const counters = Object.entries(counterHash!)
        .sort(([, a], [, b]) => b - a) // sort desc
        .reduce((r, [k, v]) => ({ total: r.total + v, regions: { ...r.regions, [k]: v } }), {
          total: 0,
          regions: {},
        })

      return Response.json({ counters })
    } catch (error) {
      return Response.json({ error: error.message }, { status: 500 })
    }
  }),
}
```

## Run locally

```bash
supabase start
supabase functions serve --no-verify-jwt --env-file supabase/functions/upstash-redis-counter/.env
```

Navigate to [http://localhost:54321/functions/v1/upstash-redis-counter](http://localhost:54321/functions/v1/upstash-redis-counter).

## Deploy

```bash
supabase functions deploy upstash-redis-counter --no-verify-jwt
supabase secrets set --env-file supabase/functions/upstash-redis-counter/.env
```
