# level-ttl

> Adds a 'ttl' option to LevelUP for puts and batches

Latest version **3.1.1** (published 2016-08-23) · MIT license · 0 weekly downloads

## Install

```sh
npm install level-ttl
pnpm add level-ttl
yarn add level-ttl
bun add level-ttl
```

## Health

**Score 23/100 (F)** — status: abandoned.

Positive: has types package; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 3.1.1 |
| Published | 2016-08-23 |
| First published | 2013-04-20 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | separate (@types/level-ttl) |
| Module format | CommonJS |
| Dependencies | 4 |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 70 |
| Maintainers | rvagg, ralphtheninja |
| Keywords | leveldb, levelup, level, ttl, whoa dude! |

## Links

- npm: https://www.npmjs.com/package/level-ttl
- Repository: https://github.com/level/level-ttl
- Issues: https://github.com/level/level-ttl/issues
- npm.io page: https://npm.io/package/level-ttl

## Dependencies (4)

- [lock](https://npm.io/package/lock.md) ~0.1.2
- [after](https://npm.io/package/after.md) >=0.8.1 <0.9.0-0
- [xtend](https://npm.io/package/xtend.md) >=4.0.0 <4.1.0-0
- [list-stream](https://npm.io/package/list-stream.md) >=1.0.0 <1.1.0-0

## Recent versions

- 3.1.1 (latest) — 2016-08-23
- 3.1.0 — 2015-05-11
- 3.0.6 — 2015-05-03
- 3.0.5 — 2015-04-28
- 3.0.4 — 2015-04-26
- 3.0.3 — 2015-03-08
- 3.0.2 — 2015-03-04
- 3.0.1 — 2015-03-02
- 3.0.0 — 2015-02-23
- 2.2.0 — 2014-12-23
- 2.1.1 — 2014-11-20
- 2.1.0 — 2014-08-28
- 2.0.1 — 2014-08-24
- 2.0.0 — 2014-08-24
- 1.0.1 — 2014-08-21
- … 10 more at https://npm.io/package/level-ttl/versions

## README

# Level TTL

<img alt="LevelDB Logo" height="100" src="http://leveldb.org/img/logo.svg">

**Add a `'ttl'` (time-to-live) option to LevelUP for `put()` and `batch()`**

[![Build Status](https://travis-ci.org/Level/level-ttl.svg?branch=master)](https://travis-ci.org/Level/level-ttl)

[![NPM](https://nodei.co/npm/level-ttl.png?downloads=true&downloadRank=true)](https://nodei.co/npm/level-ttl/)
[![NPM](https://nodei.co/npm-dl/level-ttl.png?months=6&height=3)](https://nodei.co/npm/level-ttl/)

Augment LevelUP to handle a new `'ttl'` option on `put()` and `batch()` that specifies the number of milliseconds an entry should remain in the data store. After the TTL, the entry will be automatically cleared for you.

Requires [LevelUP](https://github.com/rvagg/node-levelup), [Level](https://github.com/level/level) or [level-hyper](https://github.com/Level/level-hyper) to be installed separately.

***Note 1: Version 1.0.0 data stores are not backward compatible with previous versions. If you have unexpired entries in a data store managed by pre-1.0.0, don't expect them to expire if you upgrade to 1.0.0+.*** *This is due to a level-sublevel change. It is also recommended that you only use level-sublevel 6.0.0+ with level-ttl.*

***Note 2: `level-ttl` has partial support for `level-spaces`. It should work fine as long as you don't use the `'defaultTTL'` feature, see below. This is being worked on so we can have full support for `level-spaces` as well.***

```js
var levelup  = require('level')
  , ttl      = require('level-ttl')

var db = levelup('/tmp/foo.db')
db = ttl(db)

// --------------------------- put() --------------------------- //
// this entry will only stay in the data store for 1 hour
db.put('foo', 'bar', { ttl: 1000 * 60 * 60 }, function (err) { /* .. */ })

// -------------------------- batch() -------------------------- //
// the two 'put' entries will only stay in the data store for 1 hour
db.batch([
    { type: 'put', key: 'foo', value: 'bar' }
  , { type: 'put', key: 'bam', value: 'boom' }
  , { type: 'del', key: 'w00t' }
], { ttl: 1000 * 60 * 60 }, function (err) { /* .. */ })
```

If you put the same entry twice, you **refresh** the TTL to the *last* put operation. In this way you can build utilities like [session managers](https://github.com/rvagg/node-level-session/) for your web application where the user's session is refreshed with each visit but expires after a set period of time since their last visit.

Alternatively, for a lower write-footprint you can use the `ttl()` method that is added to your LevelUP instance which can serve to insert or update a ttl for any given key in the database (even if that key doesn't exist but may in the future! Crazy!).

```js
db.put('foo', 'bar', function (err) { /* .. */ })
db.ttl('foo', 1000 * 60 * 60, function (err) { /* .. */ })
```

**Level TTL** uses an internal scan every 10 seconds by default, this limits the available resolution of your TTL values, possibly delaying a delete for up to 10 seconds. The resolution can be tuned by passing the `'checkFrequency'` option to the `ttl()` initialiser.

```js
var db = levelup('/tmp/foo.db')
// scan for deletables every second
db = ttl(db, { checkFrequency: 1000 })

/* .. */
```

Of course, a scan takes some resources, particularly on a data store that makes heavy use of TTLs. If you don't require high accuracy for actual deletions then you can increase the `'checkFrequency'`. Note though that a scan only involves invoking a LevelUP ReadStream that returns *only the entries due to expire*, so it doesn't have to manually check through all entries with a TTL. As usual, it's best to not do too much tuning until you have you have something worth tuning!

### Default TTL

You can set a default ttl value for all your keys by passing the `'defaultTTL'` option to the `ttl()` initialiser. This can be overridden by explicitly setting the ttl value.

In the following examle `'foo'` will expire in 15 minutes while `'beep'` will expire in one minute.

```js
var db = levelup('/tmp/foo.db')
db = ttl(db, { defaultTTL: 15 * 60 * 1000 })
db.put('foo', 'bar', function (err) { /* .. */ })
db.put('beep', 'boop', { ttl: 60 * 1000 }, function (err) { /* .. */ })
```

### `opts.sub`

You can provide a custom storage for the meta data by using the `opts.sub` property. If it's set, that storage will contain all the ttl meta data. A use case for this would be to avoid mixing data and meta data in the same keyspace, since if it's not set, all data will be sharing the same keyspace.

A db for the data and a separate to store the meta data:

```js
var level = require('level')
  , ttl   = require('level-ttl')
  , meta  = level('./meta')
  , db    = ttl(level('./db'), { sub: meta })
  , batch = [
        { type: 'put', key: 'foo', value: 'foovalue' }
      , { type: 'put', key: 'bar', value: 'barvalue' }
    ]

db.batch(batch, { ttl: 100 }, function (err) {
  db.createReadStream()
    .on('data', function (data) {
      console.log('data', data)
    })
    .on('end', function () {
      meta.createReadStream()
        .on('data', function (data) {
          console.log('meta', data)
        })
    })
})
```

For more examples on this please check the tests involving `level-sublevel`.


### Shutting down

**Level TTL** uses a timer to regularly check for expiring entries (don't worry, the whole data store isn't scanned, it's very efficient!). The `db.close()` method is automatically wired to stop the timer but there is also a more explicit <b><code>db.stop()</code></b> method that will stop the timer and not pass on to a `close()` underlying LevelUP instance.

## Contributors

**Level TTL** is powered by the following hackers:

 * [Rod Vagg](https://github.com/rvagg)
 * [Matteo Collina](https://github.com/mcollina)
 * [Josh Duff](https://github.com/TehShrike)
 * [Erik Kristensen](https://github.com/ekristen)
 * [Lars-Magnus Skog](https://github.com/ralphtheninja)

## Licence

Level TTL is Copyright (c) 2013-2015 Rod Vagg [@rvagg](https://twitter.com/rvagg) and licensed under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details.

---
_Source: https://npm.io/package/level-ttl · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
