---
title: Evicting and Removing
slug: v4-4/1_39PhgLSIDX0rgeCUgyH
docTags: 
createdAt: 2023-07-28T20:04:36.552Z
---

Data storage management is essential for preventing unnecessary resource usage, which affects not only performance but also battery life and overall end-user experience.&#x20;

Having a well-thought data storage strategy ensures that your end-user environment remain memory-efficient and, as a result, your app more performant — faster load times, improved battery life, a responsive user interface, and so on.

- [Considerations](./#considerations)
- [Evict Method](./#evict-method)
- [Remove Method](./#remove-method)
- [Soft-Delete Pattern](./#soft-delete-flag)

# Considerations

Depending on your use case, use either the `evict` or `remove` methods, as well as applying soft-delete patterns to implement tools to help optimize memory usage in your app.&#x20;

:::hint{type="danger"}
To mitigate the risk of memory leaks, performance degradataion, crashes, data loss, and, if applicable, reduced battery life, it is critical that you implement a thoughtful memory management strategy in your app.
:::

When planning your approach to memory management in your app, use the following criteria to help you during the decision-making process:

| **Consideration**              | **Recommendation**                                                                                                                                                                                                                                                                                      |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Access frequency and relevance | Ensure memory is allocated only to the most relevant and frequently accessed documents by establishing an automatic process that evicts documents that are:<br />* Accessed less frequently
* No longer relevant or needed&#x20;                                                                        |
| Time-based data                | Establish an automatic process to evict or remove time-based data older than a minimum of seven days. (Until expired, time-based data remains accessible by way of local queries.)                                                                                                                      |
| Permanent data loss            | Apply careful consideration for your specific use case before invoking the  `remove` method to delete. <br />For instance, removing documents may be useful for a scenario where your end user wants to remove a specific message from a chat conversation, such as a message they've previously sent.  |

## Access Frequency and Relevance Considerations

In peer-to-peer system design, there are technical tradeoffs between the amount of data synced across peers and the timeliness of access to synced data:

- The greater the amount of data synced across connected peer devices, the more timely offline read access becomes. That is, database resilience in offline scenarios increases when there are more documents being synced across distributed peers.

- The fewer the number of documents replicated, the less the likelihood that peer devices run out of disk space and experience memory leaks, and the performance of the peer-to-peer mesh network that interconnects them degrades.

:::hint{type="info"}
For considerations on using the Evict and Subscribe methods, see [Timing Subscriptions and Evictions](./#timing-subscriptions-and-evictions).
:::

:::hint{type="info"}
For advanced concepts related to design tradeoffs in distributed system architecture, see [Cloud-Optional Design](docId:2XCufjiQ7L5tTpFxVUiA6).
:::

# Evict Method

The `EVICT` method, once invoked, immediately removes the specified document from the local Ditto store, making it inaccessible by local queries.

For complete DQL syntax, see [EVICT](docId\:ksPbI9CsHPdud0iyuow9E).

Although the document you evicted is removed from the **local** Ditto store, the document stored within **remote** Ditto stores persists.

To prevent the evicted data from reappearing on the screen in a single flicker, make sure to stop subscriptions **before** you call `EVICT`; otherwise, the subscription remains active and even if you reset the data in your end-user environment, the evicted data momentarily reappears.

:::CodeblockTabs
```swift
ditto.store
  .collection("your_collection_name")
  .find([query])
  .evict()
```

```kotlin
ditto.store["your_collection_name"]
  .find([query])
  .evict()
```

```javascript
await ditto.store
  .collection("your_collection_name")
  .find([query])
  .evict()
```

```java
ditto.store
  .collection("your_collection_name")
  .find([query])
  .evict();
```

```csharp
ditto.Store
  .Collection("your_collection_name")
  .Find([query])
  .Evict()
```

```cpp
ditto.get_store()
  .collection("your_collection_name")
  .find([query])
  .evict()
```

```rust
let collection = ditto.store()
  .collection("your_collection_name").unwrap();

collection
  .find([query])
  .evict()
  .unwrap();
```
:::

## Using Evict for Local and Live Queries

The following snippets illustrates fetching documents with the field property `color` set to the `'blue'` within the `cars` collection.

Once retrieved, Ditto automatically triggers the `evict` callback function to perform the specified purge.

:::CodeblockTabs
```swift
ditto.store
  .collection("cars")
  .find("color == 'blue'")
  .evict()
```

```kotlin
ditto.store
  .collection("cars")
  .find("color == 'blue'")
  .evict()
```

```javascript
await ditto.store
  .collection("cars")
  .find("color == 'blue'")
  .evict()
```

```java
ditto.store
  .collection("cars")
  .find("color == 'blue'")
  .evict();
```

```csharp
ditto.Store
  .Collection("cars")
  .Find("color == 'blue'")
  .Evict()
```

```cpp
ditto.get_store()
  .collection("cars")
  .find("color == 'blue'")
  .evict()
```

```rust
cars
  .find("color == 'blue'")
  .evict()
  .unwrap();
```
:::

For more information, see [Finding and Observing](docId\:HvfMp8TX4CwKI4h2xoTuy).

## Using Evict for Replication Queries

To clear documents with active subscriptions, you must first cancel the relevant subscription before calling the `evict` method in your code.

:::hint{type="warning"}
You must manage subscriptions and evictions carefully.&#x20;

If subscriptions are not properly managed prior to executing evictions, you may inadvertently disrupt the intended state, resulting in inconsistencies and unexpected behavior. For instance, the eviction process failing and the document persisting in the local Ditto store.
:::

For example, if you have an active subscription for fetching `'blue'` cars and you subsequently evict the document with the ID `'123456'` that matches the replication query, connected peers reinstate it in your local Ditto store; the document will not be cleared from the local Ditto store.&#x20;

## Timing Subscriptions and Evictions

The frequency for removing locally stored documents depends on your app's use case:

- To avoid the risk of depleting local storage capacity, consider evicting data frequently, such as once per day (if not more).
- To enhance offline datastore resiliency, you can implement app logic that allows your end users to choose which data to evict from their environments.

In addition, take a balanced approach when using the Subscribe and Evict methods; as in, consider the advantages and drawbacks of each method and use them as appropriate for the specific needs and requirements of your app.

Key considerations for using Subscription and Eviction methods include:

- Use Subscribe to sync more data across connected peers in the mesh, but be mindful of potential increased network usage that may degrade performance.

- Use Evict to remove data stored locally in an effort to manage local storage capacity and improve performance.

## Forcing Evictions

If you want to indicate that a batch of documents are irrelevant and, although they are to be retained, should *not* sync across peers, add the `isSafeToEvict` field to the document property tree. Then, use a method to alert clients to flag any documents they consider irrelevant.

:::CodeblockTabs
Ditto Document

```json
{
  "_id": "abc123",
  "color": "red",
  "mileage": 40000,
  "isSafeToEvict": true,
  "createdAt": "2023-05-22T22:24:24.217Z"
}
```
:::

To ensure that peers continue replicating documents that are considered relevant,  incorporate `isSafeToEvict == false` into their sync subscription query.&#x20;

This approach restricts replication only to documents that peers mark as `'true'` for `isSafeToEvict`. Once flagged, the peers clear irrelevant documents from their caches, all the while normal transactional operations continues without interruption.&#x20;

:::CodeblockTabs
```swift
collection
  .find("isSafeToEvict == false")
  .subscribe()
```

```kotlin
collection
  .find("isSafeToEvict == false")
  .subscribe()
```

```javascript
collection
  .find("isSafeToEvict == false")
  .subscribe()
```

```java
collection
.find("isSafeToEvict == false")
.subscribe()
```

```csharp
let liveQuery = ditto
  .store.collection('cars')
  .find('!isSafeToEvict').observeLocal((documents) => {
    console.log('these are the unarchived documents', documents)
  })
```

```cpp
collection.find("isSafeToEvict == false").subscribe()
```

```rust
collection.find("isSafeToEvict == false").subscribe()
```
:::

# Remove Method

Use the `remove` method when you want to permanently delete the document from the entire Ditto platform; that is, your local Ditto store as well as all the remote Ditto stores connected in the mesh network.

:::hint{type="danger"}
Invoking the `remove` method results in irreversible data loss. &#x20;

Once a document is removed, it is permanently eliminated throughout the Ditto system and can never be restored; however, as of Ditto version 4.0 release, if a document was previously removed, you can reverse the removal. For more information, see [Reversing Removal Operations](docId\:Q6vsBHCzgyPt1HlZgOW4E).
:::

## Removing Documents

Once you remove a document, the data it contains is wiped and a tombstone metadata is affixed to signal to remote peers that the document is deleted and no longer available.

:::hint{type="info"}
The absence of a document does not indicate that it has been deleted from the Ditto store; only the tombstone metadata marker added to the document structure indicates its deletion from the platform.&#x20;
:::

Remove may be useful for a scenario where your end user wants to remove a specific message from a chat conversation, such a message sent.&#x20;

:::CodeblockTabs
```swift
collection.findByID(docID).remove()
```

```kotlin
collection.findById(docId).remove()
```

```javascript
await ditto.store
  .collection("your_collection_name")
  .findByID("unique_document_id")
  .remove()
```

```java
ditto.store
    .collection("your_collection_name")
    .findByID("unique_document_id")
    .remove();
```

```csharp
ditto.store
  .Collection("your_collection_name")
  .FindByID("unique_document_id")
  .Remove()
```

```cpp
ditto.get_store()
  .collection("your_collection_name")
  .find_by_id("unique_document_id")
  .remove()
```

```rust
collection.find_by_id(id).remove().unwrap();
```
:::

For example, the following snippet illustrates locating the document assigned the primary key `123456` from the `cars` collection.&#x20;

Once retrieved, Ditto automatically executes the removal process:

:::CodeblockTabs
```swift
let carsCollection = ditto.store.collection("cars")

// Remove the document with ID "123456" from the collection
if let document = carsCollection.findById(123456) {
    do {
        try document.remove()
    } 
}
```

```kotlin
val carsCollection = ditto.store.collection("cars")

try {
    carsCollection.findById(123456).remove()
  }
```

```javascript
await ditto.store.collection("cars").findByID("123456").remove()
```

```java
DittoCollection carsCollection = ditto.store.collection("cars");

// Remove the document with ID "123456" from the collection
DittoDocument document = carsCollection.find("id == '123456'");
```

```csharp
ditto.store.Collection("cars").FindByID("123456").Remove()
```

```cpp
ditto.get_store().collection("cars").find_by_id("123456").remove()
```

```rust
cars.findByID("123456").remove().unwrap()
```
:::

# Soft-Delete Flag

If you need a data recovery option, instead of permanently removing the data from the local Ditto store like `EVICT`, opt for a *soft-delete pattern.&#x20;*

A soft-delete pattern is a way to flag data as inactive while retaining it for various requirements, such as archival evidence, reference integrity, prevention of potential data loss due to end-user error, and so on.

## Adding a Soft-Delete Flag

To add a soft-delete pattern, set the `isArchived` field value to `true`:

:::CodeblockTabs
JSON

```json
{
  "_id": "123abc",
  "name": "Foo",
  "isArchived": true // add this field
}
```
:::

## Querying Non-Archived Documents

To query to monitor documents that are  `NOT` archived, establish a live query using the Find method enclosed with `!isArchived`, and then construct your live query callback.&#x20;

For example, the following code demonstrates looking for documents that are not archived. Once found, the documents output, or `log`, to your console.&#x20;

```javascript
let liveQuery = ditto
  .store.collection('cars')
  .find('!isArchived').observeLocal((documents) => {
    console.log('these are the unarchived documents', documents)
  })
```

## Removing Soft-Delete Flag

To remove the flag and reactivate the document, set the `isArchived` field to `false`:&#x20;

```javascript
ditto.store.collection('cars').update((mutableDoc) => {
  mutableDoc["isArchived"] = false
})
```

