PHPackages                             marmanik/laravel-azure-table-cache - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Caching](/categories/caching)
4. /
5. marmanik/laravel-azure-table-cache

ActiveLibrary[Caching](/categories/caching)

marmanik/laravel-azure-table-cache
==================================

Azure Storage Table cache driver for Laravel

1.0.91(6d ago)09↓100%MITPHPPHP ^8.2

Since Mar 18Pushed 6d agoCompare

[ Source](https://github.com/marmanik/laravel-azure-storage-table-cache)[ Packagist](https://packagist.org/packages/marmanik/laravel-azure-table-cache)[ Docs](https://github.com/marmanik/laravel-azure-table-cache)[ RSS](/packages/marmanik-laravel-azure-table-cache/feed)WikiDiscussions master Synced today

READMEChangelog (6)Dependencies (13)Versions (10)Used By (0)

Laravel Azure Table Cache
=========================

[](#laravel-azure-table-cache)

A Laravel cache driver backed by [Azure Storage Tables](https://learn.microsoft.com/en-us/azure/storage/tables/table-storage-overview). Drop-in replacement for Redis or database cache — no extra infrastructure required if you are already on Azure.

---

How it works
------------

[](#how-it-works)

Each cache entry is stored as a row in an Azure Storage Table with three columns:

ColumnTypeDescription`PartitionKey`stringConfigurable (default: `cache`)`RowKey`stringThe cache key as-is (validated, not encoded)`CacheValue`string`base64(gzcompress(serialize($value)))``ExpiresAt`stringUnix timestamp; `0` = never expires> Azure Storage Tables has no native TTL. Expiry is enforced on read, and a provided Artisan command cleans up stale entries on a schedule.

---

Requirements
------------

[](#requirements)

- PHP **8.2+**
- Laravel **11** or **12**
- An Azure Storage account (or [Azurite](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite) for local dev)

---

Installation
------------

[](#installation)

```
composer require marmanik/laravel-azure-table-cache
```

The service provider is auto-discovered — no manual registration needed.

---

Configuration
-------------

[](#configuration)

No separate config file needed. Add the store directly to `config/cache.php`, the same way as the built-in DynamoDB driver:

```
'stores' => [

    'azure-table' => [
        'driver'        => 'azure-table',
        'account_name'  => env('AZURE_STORAGE_ACCOUNT_NAME'),
        'account_key'   => env('AZURE_STORAGE_ACCOUNT_KEY'),
        'endpoint'      => env('AZURE_STORAGE_TABLE_ENDPOINT'), // optional — for Azurite
        'table'         => env('AZURE_CACHE_TABLE', 'cache'),
        'partition_key' => env('AZURE_CACHE_PARTITION_KEY', 'cache'),
        'prefix'        => env('AZURE_CACHE_PREFIX', ''),
    ],

],
```

Add the corresponding variables to your `.env`:

```
AZURE_STORAGE_ACCOUNT_NAME=your_account_name
AZURE_STORAGE_ACCOUNT_KEY=your_base64_account_key
AZURE_CACHE_TABLE=cache
```

To use it as the **default** cache driver:

```
CACHE_STORE=azure-table
```

---

Create the Azure Table
----------------------

[](#create-the-azure-table)

Before the driver can be used the table must exist. Run the provided Artisan command once — during deployment or as part of your setup scripts:

```
php artisan azure-table-cache:create-table
```

The command is idempotent: running it against an existing table is safe.

---

Usage
-----

[](#usage)

Once the driver is registered, use it exactly like any other Laravel cache store.

### Via the default driver

[](#via-the-default-driver)

```
use Illuminate\Support\Facades\Cache;

// Store a value for 10 minutes
Cache::put('user:42:profile', $profile, now()->addMinutes(10));

// Retrieve it
$profile = Cache::get('user:42:profile');

// Store forever
Cache::forever('settings:global', $settings);

// Delete
Cache::forget('user:42:profile');

// Flush all entries in the partition
Cache::flush();
```

### Via an explicit driver

[](#via-an-explicit-driver)

```
Cache::driver('azure-table')->put('key', 'value', 300);

$value = Cache::driver('azure-table')->get('key');
```

### Remember pattern

[](#remember-pattern)

```
$posts = Cache::remember('posts:featured', now()->addHour(), function () {
    return Post::featured()->get();
});
```

### Atomic increment / decrement

[](#atomic-increment--decrement)

```
Cache::put('visits', 0, now()->addDay());

Cache::increment('visits');       // 1
Cache::increment('visits', 10);   // 11
Cache::decrement('visits', 3);    // 8
```

### Checking existence

[](#checking-existence)

```
if (Cache::has('feature:dark-mode')) {
    // ...
}
```

### Cache key rules

[](#cache-key-rules)

Cache keys are stored directly as the Azure Table `RowKey` without any encoding. Azure enforces the following restrictions — the driver will throw an `InvalidCacheKeyException` if a key violates them:

RuleDetailForbidden characters`/` `\` `#` `?` and control characters (`0x00–0x1F`, `0x7F`)Maximum length1024 bytes```
Cache::put('user:42:profile', $value, 3600);   // ✓ colon is fine
Cache::put('featured.posts', $value, 3600);    // ✓ dot is fine
Cache::put('page_1_results', $value, 3600);    // ✓ underscore is fine

Cache::put('user/42', $value, 3600);           // ✗ InvalidCacheKeyException — slash
Cache::put('search?q=hello', $value, 3600);    // ✗ InvalidCacheKeyException — question mark
```

---

### Storing multiple values at once

[](#storing-multiple-values-at-once)

```
Cache::putMany([
    'user:1' => $user1,
    'user:2' => $user2,
], now()->addMinutes(30));

$users = Cache::many(['user:1', 'user:2']);
```

---

Atomic locks
------------

[](#atomic-locks)

The driver implements Laravel's `LockProvider` contract, so `Cache::lock()` works out of the box.

Lock acquisition uses `insertEntity` under the hood — Azure Table Storage guarantees that only one concurrent caller succeeds; all others receive a 409 Conflict. If an existing lock has expired it is automatically overwritten.

```
// Acquire a lock for 10 seconds
$lock = Cache::lock('invoice:42', 10);

if ($lock->get()) {
    // Only one process reaches here at a time
    processInvoice(42);
    $lock->release();
}

// Block until the lock is available (with optional timeout)
Cache::lock('invoice:42', 10)->block(5, function () {
    processInvoice(42);
});
```

Lock keys follow the same rules as cache keys — forbidden characters (`/ \ # ?` and control characters) will throw an `InvalidCacheKeyException`.

Lock entries are stored in the same table as cache entries using a `lock:` prefix on the row key to avoid collisions.

---

Artisan commands
----------------

[](#artisan-commands)

### Create the storage table

[](#create-the-storage-table)

```
php artisan azure-table-cache:create-table
```

Creates the Azure Storage Table configured in the cache store. Safe to run multiple times — if the table already exists the command exits cleanly.

**Options:**

OptionDefaultDescription`--store``azure-table`The cache store name as defined in `config/cache.php````
# Default store name
php artisan azure-table-cache:create-table

# Custom store name
php artisan azure-table-cache:create-table --store=my-azure-store
```

### Purge expired entries

[](#purge-expired-entries)

Azure Tables has no automatic expiry. Entries are ignored on read once expired, but they remain in the table until deleted. Run this command periodically to keep the table lean:

```
php artisan azure-table-cache:purge-expired
```

**Options:**

OptionDefaultDescription`--store``azure-table`The cache store name as defined in `config/cache.php````
# Default store name
php artisan azure-table-cache:purge-expired

# Custom store name
php artisan azure-table-cache:purge-expired --store=my-azure-store
```

Schedule it in `routes/console.php` (Laravel 11+):

```
use Illuminate\Support\Facades\Schedule;

Schedule::command('azure-table-cache:purge-expired')->daily();

// With a custom store name
Schedule::command('azure-table-cache:purge-expired --store=my-azure-store')->daily();
```

Or in `app/Console/Kernel.php` (Laravel 10):

```
protected function schedule(Schedule $schedule): void
{
    $schedule->command('azure-table-cache:purge-expired')->daily();
}
```

---

Local development with Azurite
------------------------------

[](#local-development-with-azurite)

[Azurite](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite) is the official Azure Storage emulator. Run it with Docker:

```
docker run -p 10002:10002 mcr.microsoft.com/azure-storage/azurite azurite-table
```

Then configure your store in `config/cache.php`:

```
'azure-table' => [
    'driver'        => 'azure-table',
    'account_name'  => env('AZURE_STORAGE_ACCOUNT_NAME', 'devstoreaccount1'),
    'account_key'   => env('AZURE_STORAGE_ACCOUNT_KEY', 'Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=='),
    'endpoint'      => env('AZURE_STORAGE_TABLE_ENDPOINT', 'http://127.0.0.1:10002/devstoreaccount1'),
    'table'         => env('AZURE_CACHE_TABLE', 'cache'),
    'partition_key' => env('AZURE_CACHE_PARTITION_KEY', 'cache'),
    'prefix'        => env('AZURE_CACHE_PREFIX', ''),
],
```

> The account name and key above are the well-known Azurite defaults — they are not real credentials.

---

Multiple apps sharing one table
-------------------------------

[](#multiple-apps-sharing-one-table)

Use a unique `partition_key` or `prefix` per app to avoid key collisions:

```
# App 1
AZURE_CACHE_PARTITION_KEY=app1
AZURE_CACHE_PREFIX=app1_

# App 2
AZURE_CACHE_PARTITION_KEY=app2
AZURE_CACHE_PREFIX=app2_
```

---

Testing
-------

[](#testing)

Run the test suite:

```
composer test
```

Run static analysis:

```
composer analyse
```

Format code:

```
composer format
```

---

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for recent changes.

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

43

—

FairBetter than 91% of packages

Maintenance99

Actively maintained with recent releases

Popularity7

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

9

Last Release

6d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/5f92b39f6f2b1ad41432382e70a1a80394fc33137ebe7761c644af4f442ad86b?d=identicon)[MarmaNik](/maintainers/MarmaNik)

---

Top Contributors

[![marmanik](https://avatars.githubusercontent.com/u/5727095?v=4)](https://github.com/marmanik "marmanik (12 commits)")

---

Tags

laravelcacheazureazure storagemarmaniktable-storage

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/marmanik-laravel-azure-table-cache/health.svg)

```
[![Health](https://phpackages.com/badges/marmanik-laravel-azure-table-cache/health.svg)](https://phpackages.com/packages/marmanik-laravel-azure-table-cache)
```

###  Alternatives

[spatie/laravel-responsecache

Speed up a Laravel application by caching the entire response

2.8k7.9M43](/packages/spatie-laravel-responsecache)[yediyuz/laravel-cloudflare-cache

laravel-cloudflare-cache

28232.4k](/packages/yediyuz-laravel-cloudflare-cache)[dragon-code/laravel-cache

An improved interface for working with cache

6844.1k8](/packages/dragon-code-laravel-cache)[antennaio/laravel-clyde

Image uploads and manipulation for Laravel, a wrapper around Glide

302.6k](/packages/antennaio-laravel-clyde)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
