> ## Documentation Index
> Fetch the complete documentation index at: https://upstash.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# EXEC

> Execute queued commands.

Use `EXEC` to run the commands queued since [`MULTI`](/docs/redis/commands/transactions/multi).

They execute one after another with no other client's command in between, and the reply is an array holding one result per queued command, in order. Errors raised by individual commands appear in that array rather than stopping the rest, so check each entry.

If any key watched with [`WATCH`](/docs/redis/commands/transactions/watch) was modified after it was watched, the transaction is not executed at all and the reply is null, which is the signal to read the data again and retry. Watches are cleared afterwards either way.

The raw command is TCP-only. Over HTTP, use the transaction or pipeline API of an Upstash SDK instead of sending this command directly.

## Syntax

```redis theme={"system"}
EXEC
```

## Arguments

This command takes no arguments.

## Important points

* The raw command is TCP-only. For HTTP, use an Upstash SDK transaction API rather than sending this command directly.

## Response

The reply reports the result of the operation. Error replies have the same shape in RESP2 and RESP3 and are surfaced as exceptions by the SDKs below.

| Protocol | Reply                                                      |
| -------- | ---------------------------------------------------------- |
| RESP2    | Array of command replies or Null bulk string or null array |
| RESP3    | Array of command replies or Null                           |

<Note>
  Client libraries often decode bulk strings, maps, sets, and numeric strings into language-native values. The table describes the Redis wire reply.
</Note>

## Examples

TCP examples use the TLS `REDIS_URL` from the Upstash console. REST examples use `UPSTASH_REDIS_REST_URL` and `UPSTASH_REDIS_REST_TOKEN`.

<AccordionGroup>
  <Accordion title="Redis CLI" icon="terminal">
    ```bash theme={"system"}
    MULTI
    SET balance 100
    EXEC
    ```
  </Accordion>

  <Accordion title="ioredis" icon="node-js" iconType="brands">
    ```ts theme={"system"}
    import Redis from "ioredis";

    const client = new Redis(process.env.REDIS_URL!);
    const result = await client.multi().set("balance", "100").exec();
    ```
  </Accordion>

  <Accordion title="node-redis" icon="node-js" iconType="brands">
    ```ts theme={"system"}
    import { createClient } from "redis";

    const client = await createClient({ url: process.env.REDIS_URL }).connect();
    const result = await client.multi().set("balance", "100").exec();
    ```
  </Accordion>

  <Accordion title="redis-py" icon="python" iconType="brands">
    ```python theme={"system"}
    import os
    import redis

    client = redis.from_url(os.environ["REDIS_URL"])
    with client.pipeline(transaction=True) as pipe:
        result = pipe.set("balance", "100").execute()
    ```
  </Accordion>

  <Accordion title="go-redis" icon="golang" iconType="brands">
    ```go theme={"system"}
    ctx := context.Background()
    opts, err := redis.ParseURL(os.Getenv("REDIS_URL"))
    if err != nil { panic(err) }
    client := redis.NewClient(opts)

    pipe := client.TxPipeline()
    pipe.Set(ctx, "balance", "100", 0)
    result, err := pipe.Exec(ctx)
    if err != nil { panic(err) }
    ```
  </Accordion>

  <Accordion title="jedis" icon="java" iconType="brands">
    ```java theme={"system"}
    import java.net.URI;
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.Transaction;

    try (Jedis jedis = new Jedis(new URI(System.getenv("REDIS_URL")));
         Transaction transaction = jedis.multi()) {
      transaction.set("balance", "100");
      Object result = transaction.exec();
    }
    ```
  </Accordion>

  <Accordion title="redis-rs" icon="rust" iconType="brands">
    ```rust theme={"system"}
    fn main() -> redis::RedisResult<()> {
        let url = std::env::var("REDIS_URL").expect("REDIS_URL is not set");
        let client = redis::Client::open(url)?;
        let mut connection = client.get_connection()?;

        redis::pipe()
            .atomic()
            .set("balance", "100")
            .ignore()
            .query::<()>(&mut connection)?;
        Ok(())
    }
    ```
  </Accordion>
</AccordionGroup>


## Related topics

- [CLI](/docs/agent-resources/cli.md)
- [Vercel AI SDK](/docs/workflow/integrations/aisdk.md)
- [Prevent Retries](/docs/workflow/features/retries/prevent-retries.md)
- [General](/docs/workflow/troubleshooting/general.md)
- [Dynamic Workflows](/docs/workflow/examples/dynamicWorkflow.md)
