## Create and update

To write data to the DataStore, pass an instance of a model to `Amplify.DataStore.save()`:

import ios2 from "/src/fragments/lib-v1/datastore/ios/data-access/save-snippet.mdx";

<Fragments fragments={{ios: ios2}} />

import android3 from "/src/fragments/lib-v1/datastore/android/data-access/save-snippet.mdx";

<Fragments fragments={{android: android3}} />

import flutter4 from "/src/fragments/lib-v1/datastore/flutter/data-access/save-snippet.mdx";

<Fragments fragments={{flutter: flutter4}} />

The `save` method creates a new record, or in the event that one already exists in the local store, it updates the record.

import ios6 from "/src/fragments/lib-v1/datastore/ios/data-access/update-snippet.mdx";

<Fragments fragments={{ios: ios6}} />

import android7 from "/src/fragments/lib-v1/datastore/android/data-access/update-snippet.mdx";

<Fragments fragments={{android: android7}} />

import flutter8 from "/src/fragments/lib-v1/datastore/flutter/data-access/update-snippet.mdx";

<Fragments fragments={{flutter: flutter8}} />

<Callout warning>

  **Avoid working with stale data!**

  Model instances which store values, such as those from the results of a `DataStore.Query` operation, can become stale and outdated when their properties are updated. This can be the result of a manual change or even a side effect of [real time data](/lib-v1/datastore/sync#distributed-data) being received by the application. In order to ensure you are performing mutations on the latest committed state to the system, either perform a query directly before the `DataStore.save()` operation or observe the model to keep the state updated at all times and perform mutations on that latest state referencing the model instance. The preceding example demonstrates one approach. The following example demonstrates the `observeQuery` approach.

</Callout>

import ios_observe_update from "/src/fragments/lib-v1/datastore/ios/data-access/observe-update-snippet.mdx";

<Fragments fragments={{ios: ios_observe_update}} />

import android_observe_update from "/src/fragments/lib-v1/datastore/android/data-access/observe-update-snippet.mdx";

<Fragments fragments={{android: android_observe_update}} />

import flutter_observe_update from "/src/fragments/lib-v1/datastore/flutter/data-access/observe-update-snippet.mdx";

<Fragments fragments={{flutter: flutter_observe_update}} />

## Delete

To delete an item, simply pass in an instance.

import ios10 from "/src/fragments/lib-v1/datastore/ios/data-access/delete-snippet.mdx";

<Fragments fragments={{ios: ios10}} />

import android11 from "/src/fragments/lib-v1/datastore/android/data-access/delete-snippet.mdx";

<Fragments fragments={{android: android11}} />

import flutter12 from "/src/fragments/lib-v1/datastore/flutter/data-access/delete-snippet.mdx";

<Fragments fragments={{flutter: flutter12}} />

## Query Data

Queries are performed against the _local store_. When cloud synchronization is enabled, the local store is updated in the background by the DataStore Sync Engine.

For more advanced filtering, such as matching arbitrary field values on an object, you can supply a query predicate.

import ios14 from "/src/fragments/lib-v1/datastore/ios/data-access/query-basic-snippet.mdx";

<Fragments fragments={{ios: ios14}} />

import android15 from "/src/fragments/lib-v1/datastore/android/data-access/query-basic-snippet.mdx";

<Fragments fragments={{android: android15}} />

import flutter16 from "/src/fragments/lib-v1/datastore/flutter/data-access/query-basic-snippet.mdx";

<Fragments fragments={{flutter: flutter16}} />

### Predicates

Predicates are filters that can be used to match items in the DataStore. When applied to a query(), they constrain the returned results. When applied to a save(), they act as a pre-requisite for updating the data. You can match against fields in your schema by using the following predicates:

import iOSPredicates from "/src/fragments/lib-v1/datastore/ios/data-access/query-predicate-types.mdx";

<Fragments fragments={{ios: iOSPredicates}} />

import androidPredicates from "/src/fragments/lib-v1/datastore/android/data-access/query-predicate-types.mdx";

<Fragments fragments={{android: androidPredicates}} />

import flutterPredicates from "/src/fragments/lib-v1/datastore/flutter/data-access/query-predicate-types.mdx";

<Fragments fragments={{flutter: flutterPredicates}} />

For example if you wanted a list of all `Post` Models that have a `rating` greater than 4:

import ios19 from "/src/fragments/lib-v1/datastore/ios/data-access/query-predicate-snippet.mdx";

<Fragments fragments={{ios: ios19}} />

import android20 from "/src/fragments/lib-v1/datastore/android/data-access/query-predicate-snippet.mdx";

<Fragments fragments={{android: android20}} />

import flutter21 from "/src/fragments/lib-v1/datastore/flutter/data-access/query-predicate-snippet.mdx";

<Fragments fragments={{flutter: flutter21}} />

Multiple conditions can also be used, like the ones defined in [GraphQL Transform condition statements](/cli/graphql/data-modeling). For example, fetch all posts that have a rating greater than `4` and are `ACTIVE`:

import ios23 from "/src/fragments/lib-v1/datastore/ios/data-access/query-predicate-multiple-snippet.mdx";

<Fragments fragments={{ios: ios23}} />

import android24 from "/src/fragments/lib-v1/datastore/android/data-access/query-predicate-multiple-snippet.mdx";

<Fragments fragments={{android: android24}} />

import flutter25 from "/src/fragments/lib-v1/datastore/flutter/data-access/query-predicate-multiple-snippet.mdx";

<Fragments fragments={{flutter: flutter25}} />

Alternatively, the `or` logical operator can also be used:

import ios27 from "/src/fragments/lib-v1/datastore/ios/data-access/query-predicate-or-snippet.mdx";

<Fragments fragments={{ios: ios27}} />

import android28 from "/src/fragments/lib-v1/datastore/android/data-access/query-predicate-or-snippet.mdx";

<Fragments fragments={{android: android28}} />

import flutter29 from "/src/fragments/lib-v1/datastore/flutter/data-access/query-predicate-or-snippet.mdx";

<Fragments fragments={{flutter: flutter29}} />

import ios31 from "/src/fragments/lib-v1/datastore/native_common/sort.mdx";

<Fragments fragments={{ios: ios31}} />

import android32 from "/src/fragments/lib-v1/datastore/native_common/sort.mdx";

<Fragments fragments={{android: android32}} />

import flutter33 from "/src/fragments/lib-v1/datastore/native_common/sort.mdx";

<Fragments fragments={{flutter: flutter33}} />

### Pagination

Query results can also be paginated by passing in a `page` number (starting at 0) and an optional `limit` (defaults to 100). This will return a list of the first 100 items:

import ios35 from "/src/fragments/lib-v1/datastore/ios/data-access/query-pagination-snippet.mdx";

<Fragments fragments={{ios: ios35}} />

import android36 from "/src/fragments/lib-v1/datastore/android/data-access/query-pagination-snippet.mdx";

<Fragments fragments={{android: android36}} />

import flutter37 from "/src/fragments/lib-v1/datastore/flutter/data-access/query-pagination-snippet.mdx";

<Fragments fragments={{flutter: flutter37}} />

### Query, then observe changes

<Callout>

  To both query _and_ observe subsequent changes to a Model, consider using
  [`observeQuery`](/lib-v1/datastore/real-time#displaying-data-during-the-sync-process-with-observequery).

</Callout>
