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

# Environment Variables

> Complete reference of environment variables used by Medusa

# Environment Variables

This page lists all environment variables that Medusa recognizes and uses for configuration.

<Note>
  Environment variables are loaded from `.env` files in development. In production, set them in your hosting environment.
</Note>

## Required Variables

These variables are required for Medusa to run:

### DATABASE\_URL

PostgreSQL connection string.

```bash theme={null}
DATABASE_URL=postgres://user:password@host:port/dbname
```

**Format**: `postgres://[user][:password]@[host][:port]/[dbname]`

**Default**: `postgres://localhost/medusa-starter-default`

### JWT\_SECRET

Secret key for signing JWT tokens.

```bash theme={null}
JWT_SECRET=your-super-secret-jwt-key
```

**Default**: `supersecret` (development only)

<Warning>
  In production, this must be set to a strong, random value. Use at least 32 random characters.
</Warning>

**Generate a secure secret**:

```bash theme={null}
node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
```

### COOKIE\_SECRET

Secret key for signing session cookies.

```bash theme={null}
COOKIE_SECRET=your-super-secret-cookie-key
```

**Default**: `supersecret` (development only)

<Warning>
  In production, this must be set to a strong, random value different from JWT\_SECRET.
</Warning>

## HTTP Configuration

### PORT

Port number for the HTTP server.

```bash theme={null}
PORT=9000
```

**Default**: `9000`

### NODE\_ENV

Application environment.

```bash theme={null}
NODE_ENV=production
```

**Values**: `development`, `production`, `prod`

**Default**: `development`

### STORE\_CORS

Allowed CORS origins for store routes.

```bash theme={null}
STORE_CORS=https://storefront.example.com,https://shop.example.com
```

**Default**: `http://localhost:8000`

**Format**: Comma-separated list of URLs

### ADMIN\_CORS

Allowed CORS origins for admin routes.

```bash theme={null}
ADMIN_CORS=https://admin.example.com,https://dashboard.example.com
```

**Default**: `http://localhost:7000,http://localhost:7001,http://localhost:5173`

**Format**: Comma-separated list of URLs

### AUTH\_CORS

Allowed CORS origins for auth routes.

```bash theme={null}
AUTH_CORS=https://admin.example.com
```

**Default**: Same as `ADMIN_CORS`

**Format**: Comma-separated list of URLs

## JWT Configuration

### JWT\_PUBLIC\_KEY

Public key for asymmetric JWT verification.

```bash theme={null}
JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nMIIBIjAN...\n-----END PUBLIC KEY-----"
```

**Default**: Not set (uses symmetric signing with JWT\_SECRET)

<Note>
  When using asymmetric JWT, configure `jwtOptions.algorithm` and `jwtVerifyOptions.algorithms` in medusa-config.ts.
</Note>

## Redis Configuration

### REDIS\_URL

Redis connection URL.

```bash theme={null}
REDIS_URL=redis://localhost:6379
```

**Format**: `redis://[user][:password]@[host][:port]`

**Default**: Not set (uses in-memory implementations)

<Warning>
  For production, Redis is strongly recommended for the event bus, cache, and workflow engine.
</Warning>

### CACHE\_REDIS\_URL

Separate Redis instance for caching.

```bash theme={null}
CACHE_REDIS_URL=redis://localhost:6380
```

**Default**: Falls back to `REDIS_URL`

## Worker Mode

### MEDUSA\_WORKER\_MODE

Determines how the instance handles HTTP requests and background jobs.

```bash theme={null}
MEDUSA_WORKER_MODE=server
```

**Values**:

* `shared`: Handle both HTTP and jobs (default)
* `server`: Only handle HTTP requests
* `worker`: Only handle background jobs

**Default**: `shared`

**Production setup**:

```bash theme={null}
# Server instance
MEDUSA_WORKER_MODE=server npm run start

# Worker instance
MEDUSA_WORKER_MODE=worker npm run start
```

## Admin Configuration

### MEDUSA\_BACKEND\_URL

Backend URL for the admin dashboard.

```bash theme={null}
MEDUSA_BACKEND_URL=https://api.example.com
```

**Default**: `/` (browser origin)

### DISABLE\_ADMIN

Disable the admin dashboard.

```bash theme={null}
DISABLE_ADMIN=true
```

**Default**: `false`

### STOREFRONT\_URL

Storefront URL for generating customer-facing links from admin.

```bash theme={null}
STOREFRONT_URL=https://shop.example.com
```

**Default**: Not set

## Logging

### LOG\_LEVEL

Logging level for the application.

```bash theme={null}
LOG_LEVEL=info
```

**Values**: `error`, `warn`, `info`, `debug`

**Default**: `info`

**Production recommendation**: `error` or `warn`

## Medusa Cloud

These variables are used when deploying to Medusa Cloud:

### EXECUTION\_CONTEXT

```bash theme={null}
EXECUTION_CONTEXT=medusa-cloud
```

Enables Medusa Cloud-specific configurations.

### MEDUSA\_CLOUD\_ENVIRONMENT\_HANDLE

```bash theme={null}
MEDUSA_CLOUD_ENVIRONMENT_HANDLE=prod-env-abc123
```

### MEDUSA\_CLOUD\_SANDBOX\_HANDLE

```bash theme={null}
MEDUSA_CLOUD_SANDBOX_HANDLE=sandbox-abc123
```

### MEDUSA\_CLOUD\_API\_KEY

```bash theme={null}
MEDUSA_CLOUD_API_KEY=mck_abc123...
```

### MEDUSA\_CLOUD\_WEBHOOK\_SECRET

```bash theme={null}
MEDUSA_CLOUD_WEBHOOK_SECRET=whsec_abc123...
```

### MEDUSA\_CLOUD\_EMAILS\_ENDPOINT

```bash theme={null}
MEDUSA_CLOUD_EMAILS_ENDPOINT=https://emails.medusacloud.com
```

### MEDUSA\_CLOUD\_PAYMENTS\_ENDPOINT

```bash theme={null}
MEDUSA_CLOUD_PAYMENTS_ENDPOINT=https://payments.medusacloud.com
```

### MEDUSA\_CLOUD\_OAUTH\_AUTHORIZE\_ENDPOINT

```bash theme={null}
MEDUSA_CLOUD_OAUTH_AUTHORIZE_ENDPOINT=https://oauth.medusacloud.com/authorize
```

### MEDUSA\_CLOUD\_OAUTH\_TOKEN\_ENDPOINT

```bash theme={null}
MEDUSA_CLOUD_OAUTH_TOKEN_ENDPOINT=https://oauth.medusacloud.com/token
```

### MEDUSA\_CLOUD\_OAUTH\_CALLBACK\_URL

```bash theme={null}
MEDUSA_CLOUD_OAUTH_CALLBACK_URL=https://admin.example.com/app/login?auth_provider=cloud
```

### MEDUSA\_CLOUD\_OAUTH\_DISABLED

```bash theme={null}
MEDUSA_CLOUD_OAUTH_DISABLED=true
```

## Session Configuration

### SESSION\_STORE

Session storage backend.

```bash theme={null}
SESSION_STORE=dynamodb
```

**Values**: `dynamodb` (when using DynamoDB for sessions)

**Default**: In-memory or Redis (based on `REDIS_URL`)

### DynamoDB Session Variables

When using DynamoDB for session storage:

```bash theme={null}
DYNAMO_DB_SESSIONS_TABLE=medusa-sessions
DYNAMO_DB_SESSIONS_PREFIX=sess:
DYNAMO_DB_SESSIONS_HASH_KEY=id
DYNAMO_DB_SESSIONS_READ_UNITS=5
DYNAMO_DB_SESSIONS_WRITE_UNITS=5
DYNAMO_DB_SESSIONS_CREATE_TABLE=true
```

## File Storage (S3)

When using S3 for file storage:

### S3\_BUCKET

```bash theme={null}
S3_BUCKET=my-medusa-files
```

### S3\_REGION

```bash theme={null}
S3_REGION=us-east-1
```

### S3\_ACCESS\_KEY\_ID

```bash theme={null}
S3_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
```

### S3\_SECRET\_ACCESS\_KEY

```bash theme={null}
S3_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
```

### S3\_ENDPOINT

```bash theme={null}
S3_ENDPOINT=https://s3.us-east-1.amazonaws.com
```

### S3\_FILE\_URL

```bash theme={null}
S3_FILE_URL=https://my-bucket.s3.amazonaws.com
```

### S3\_PREFIX

```bash theme={null}
S3_PREFIX=uploads/
```

## Payment Providers

### Stripe

```bash theme={null}
STRIPE_API_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
```

### PayPal

```bash theme={null}
PAYPAL_CLIENT_ID=...
PAYPAL_CLIENT_SECRET=...
PAYPAL_MODE=sandbox  # or 'live'
```

## Notification Providers

### SendGrid

```bash theme={null}
SENDGRID_API_KEY=SG....
SENDGRID_FROM=noreply@example.com
```

### Mailchimp

```bash theme={null}
MAILCHIMP_API_KEY=...
MAILCHIMP_LIST_ID=...
```

## Feature Flags

### MEDUSA\_FF\_TRANSLATION

Enable translation module.

```bash theme={null}
MEDUSA_FF_TRANSLATION=true
```

**Default**: `false`

### MEDUSA\_FF\_RBAC

Enable role-based access control.

```bash theme={null}
MEDUSA_FF_RBAC=true
```

**Default**: `false`

### ENABLE\_INDEX\_MODULE

Enable the index/search module.

```bash theme={null}
ENABLE_INDEX_MODULE=true
```

**Default**: `false`

## Database Internal Variables

These are used internally for database connection handling:

### \_\_MEDUSA\_DB\_CONNECTION\_MAX\_RETRIES

Maximum retries for database connection.

```bash theme={null}
__MEDUSA_DB_CONNECTION_MAX_RETRIES=5
```

**Default**: `5`

### \_\_MEDUSA\_DB\_CONNECTION\_RETRY\_DELAY

Delay between connection retries in milliseconds.

```bash theme={null}
__MEDUSA_DB_CONNECTION_RETRY_DELAY=1000
```

**Default**: `1000`

### DB\_MIGRATION\_CONCURRENCY

Number of concurrent migrations to run.

```bash theme={null}
DB_MIGRATION_CONCURRENCY=5
```

**Default**: Unlimited (or 1 if using pgstream)

## Module-Specific Database URLs

You can configure separate databases for specific modules:

### MEDUSA\_DATABASE\_URL

Shared database for all modules.

```bash theme={null}
MEDUSA_DATABASE_URL=postgres://localhost/medusa_shared
```

### Module Database URLs

```bash theme={null}
# Product module
PRODUCT_DATABASE_URL=postgres://localhost/medusa_products

# Order module
ORDER_DATABASE_URL=postgres://localhost/medusa_orders

# Customer module
CUSTOMER_DATABASE_URL=postgres://localhost/medusa_customers
```

Format: `{MODULE_NAME}_DATABASE_URL`

## Example .env File

Here's a complete example for production:

```bash title=".env" theme={null}
# Environment
NODE_ENV=production
PORT=9000
LOG_LEVEL=warn

# Database
DATABASE_URL=postgres://medusa:secure_password@db.example.com:5432/medusa_prod?sslmode=require

# Redis
REDIS_URL=redis://:password@redis.example.com:6379

# Secrets
JWT_SECRET=<generated-secret-key>
COOKIE_SECRET=<generated-secret-key>

# CORS
STORE_CORS=https://shop.example.com
ADMIN_CORS=https://admin.example.com
AUTH_CORS=https://admin.example.com

# Admin
MEDUSA_BACKEND_URL=https://api.example.com
STOREFRONT_URL=https://shop.example.com

# File Storage (S3)
S3_BUCKET=medusa-prod-files
S3_REGION=us-east-1
S3_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
S3_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

# Payment (Stripe)
STRIPE_API_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...

# Notifications (SendGrid)
SENDGRID_API_KEY=SG....
SENDGRID_FROM=orders@example.com

# Worker Mode
MEDUSA_WORKER_MODE=server
```

## Security Best Practices

<Warning>
  **Never commit `.env` files to version control.** Add `.env` to your `.gitignore` file.
</Warning>

1. **Use strong secrets**: Generate random values for JWT\_SECRET and COOKIE\_SECRET
2. **Different secrets per environment**: Don't reuse secrets between development, staging, and production
3. **Rotate secrets regularly**: Update secrets periodically and after security incidents
4. **Use secret management**: Consider using AWS Secrets Manager, HashiCorp Vault, or similar
5. **Limit access**: Only grant access to environment variables to those who need it
6. **Audit changes**: Track who changes environment variables and when

## Loading Environment Variables

### Development

Medusa automatically loads variables from `.env` files:

```bash theme={null}
# .env file in project root
DATABASE_URL=postgres://localhost/medusa_dev
JWT_SECRET=dev-secret
```

### Production

Set environment variables in your hosting platform:

* **Docker**: Use `-e` flag or `docker-compose.yml`
* **Kubernetes**: ConfigMaps and Secrets
* **Heroku**: Config Vars in dashboard or CLI
* **AWS**: Systems Manager Parameter Store or Secrets Manager
* **Vercel/Netlify**: Environment variables in dashboard

### Multiple Environment Files

You can use different `.env` files:

```bash theme={null}
# .env.development
DATABASE_URL=postgres://localhost/medusa_dev

# .env.staging  
DATABASE_URL=postgres://staging-db/medusa_staging

# .env.production
DATABASE_URL=postgres://prod-db/medusa_prod
```

Load specific file:

```bash theme={null}
node -r dotenv/config --env-file=.env.staging server.js
```
