diff --git a/src/routes/docs/products/databases/+layout.svelte b/src/routes/docs/products/databases/+layout.svelte
index 87f1ffb5a3..8708aa839e 100644
--- a/src/routes/docs/products/databases/+layout.svelte
+++ b/src/routes/docs/products/databases/+layout.svelte
@@ -1,11 +1,8 @@
diff --git a/src/routes/docs/products/databases/+page.markdoc b/src/routes/docs/products/databases/+page.markdoc
index 9217bde1e6..094c363eb5 100644
--- a/src/routes/docs/products/databases/+page.markdoc
+++ b/src/routes/docs/products/databases/+page.markdoc
@@ -4,16 +4,30 @@ title: Databases
description: Store and query structured data with Appwrite Databases. Databases provide performant and scalable storage for your application, business, and user data.
---
-Appwrite Databases let you store and query structured data.
+Appwrite Databases let you store and query structured data.
Databases provide high-performance and scalable data storage for your key application, business, and user data.
{% info title="Looking for file storage?" %}
Databases store data, if you need to store files like images, PDFs or videos, use [Appwrite Storage](/docs/products/storage).
{% /info %}
-You can organize data into databases, tables, and rows. You can also paginate, order, and query rows.
+Appwrite supports two database backends, each optimized for different workloads:
+
+| | Tables DB | Documents DB |
+|---|---|---|
+| **Backed by** | MariaDB (SQL) | MongoDB (NoSQL) |
+| **Terminology** | Tables, rows, columns | Collections, documents, attributes |
+| **Best for** | Relational data, geo queries, CSV workflows | Flexible schemas, large attribute counts |
+| **Spatial/Geo** | Full support | Not available |
+| **CSV import/export** | Supported | Not available |
+
+You can organize data into databases, tables (or collections), and rows (or documents). You can also paginate, order, and query your data.
For complex business logic, Appwrite supports relationships to help you model your data.
-{% arrow_link href="/docs/products/databases/quick-start" %}
-Quick start
+{% arrow_link href="/docs/products/databases/tablesdb/quick-start" %}
+Get started with Tables DB
+{% /arrow_link %}
+
+{% arrow_link href="/docs/products/databases/documentsdb/quick-start" %}
+Get started with Documents DB
{% /arrow_link %}
\ No newline at end of file
diff --git a/src/routes/docs/products/databases/ai-suggestions/+page.markdoc b/src/routes/docs/products/databases/ai-suggestions/+page.markdoc
index b6b653ad4a..6f5cb2c7a2 100644
--- a/src/routes/docs/products/databases/ai-suggestions/+page.markdoc
+++ b/src/routes/docs/products/databases/ai-suggestions/+page.markdoc
@@ -1,19 +1,19 @@
---
layout: article
title: AI suggestions
-description: Use AI suggestions to automatically generate database schemas. Learn how to create tables with recommended columns and indexes based on your table name and context.
+description: Use AI suggestions to automatically generate database schemas. Learn how to create tables or collections with recommended columns/attributes and indexes based on your name and context.
---
-AI suggestions generate columns and indexes for your tables based on the table name, existing database structure, and optional context you provide.
+AI suggestions generate columns (Tables DB) or attributes (Documents DB) and indexes for your tables or collections based on the name, existing database structure, and optional context you provide.
This feature analyzes your database to recommend appropriate schema designs that follow best practices.
-{% section #create-table step=1 title="Create table" %}
-Navigate to **Databases** in the Appwrite Console, select your database, and click **Create table**.
+{% section #create-table step=1 title="Create table or collection" %}
+Navigate to **Databases** in the Appwrite Console, select your database, and click **Create table** (Tables DB) or **Create collection** (Documents DB).
-Enter a descriptive table name. AI suggestions will use this name to generate relevant columns and indexes.
+Enter a descriptive name. AI suggestions will use this name to generate relevant columns/attributes and indexes.
{% /section %}
{% section #enable-suggestions step=2 title="Enable AI suggestions" %}
-In the table creation dialog, enable **AI suggestions**.
+In the table or collection creation dialog, enable **AI suggestions**.
{% only_dark %}

@@ -22,13 +22,13 @@ In the table creation dialog, enable **AI suggestions**.

{% /only_light %}
-Optionally, provide additional context about your use case to refine the suggestions. For example, if creating an `Orders` table, you might add context like "e-commerce orders with payment tracking."
+Optionally, provide additional context about your use case to refine the suggestions. For example, if creating an `Orders` table or collection, you might add context like "e-commerce orders with payment tracking."
-Click **Generate suggestions** to analyze your table name and database structure.
+Click **Generate suggestions** to analyze your table or collection name and database structure.
{% /section %}
{% section #review-suggestions step=3 title="Review suggestions" %}
-AI suggestions will generate recommended columns and indexes for your table.
+AI suggestions will generate recommended columns or attributes and indexes for your table or collection.
{% only_dark %}

@@ -52,7 +52,7 @@ You can modify any suggestion before applying:
- Remove suggestions you don't need
- Add additional columns manually
-Click **Apply** to apply your schema. The table will be created with your approved columns and indexes.
+Click **Apply** to apply your schema. The table or collection will be created with your approved columns or attributes and indexes.
{% info title="Manual columns" %}
You can always add, modify, or remove [columns](/docs/products/databases/tables#columns) after table creation by navigating to your table's **Columns** tab.
diff --git a/src/routes/docs/products/databases/atomic-numeric-operations/+page.ts b/src/routes/docs/products/databases/atomic-numeric-operations/+page.ts
new file mode 100644
index 0000000000..25a1650eb0
--- /dev/null
+++ b/src/routes/docs/products/databases/atomic-numeric-operations/+page.ts
@@ -0,0 +1,6 @@
+import type { PageLoad } from './$types';
+import { redirect } from '@sveltejs/kit';
+
+export const load: PageLoad = async () => {
+ redirect(303, '/docs/products/databases/tablesdb/atomic-numeric-operations');
+};
diff --git a/src/routes/docs/products/databases/bulk-operations/+page.ts b/src/routes/docs/products/databases/bulk-operations/+page.ts
new file mode 100644
index 0000000000..4ed5c2eda8
--- /dev/null
+++ b/src/routes/docs/products/databases/bulk-operations/+page.ts
@@ -0,0 +1,6 @@
+import type { PageLoad } from './$types';
+import { redirect } from '@sveltejs/kit';
+
+export const load: PageLoad = async () => {
+ redirect(303, '/docs/products/databases/tablesdb/bulk-operations');
+};
diff --git a/src/routes/docs/products/databases/csv-exports/+page.markdoc b/src/routes/docs/products/databases/csv-exports/+page.markdoc
index ea524f4cc7..479cd54928 100644
--- a/src/routes/docs/products/databases/csv-exports/+page.markdoc
+++ b/src/routes/docs/products/databases/csv-exports/+page.markdoc
@@ -4,6 +4,10 @@ title: CSV exports
description: Export table data to CSV files from the Console. Share clean datasets with your team without writing custom scripts.
---
+{% info title="Tables DB only" %}
+CSV exports are only available with **Tables DB** (MariaDB). Documents DB (MongoDB) does not support CSV exports.
+{% /info %}
+
Appwrite's CSV Export feature allows you to export rows from a table to a CSV file. This is especially useful for reporting, sharing data with non-technical team members, creating custom backups, or handing off datasets to analytics tools.
This feature is available in both Appwrite Cloud and the self-hosted version.
diff --git a/src/routes/docs/products/databases/csv-imports/+page.markdoc b/src/routes/docs/products/databases/csv-imports/+page.markdoc
index 341c96eeef..9081588bf9 100644
--- a/src/routes/docs/products/databases/csv-imports/+page.markdoc
+++ b/src/routes/docs/products/databases/csv-imports/+page.markdoc
@@ -4,6 +4,10 @@ title: CSV imports
description: Master row imports with Appwrite's CSV Import feature. Learn how to create rows within your tables by uploading a CSV file.
---
+{% info title="Tables DB only" %}
+CSV imports are only available with **Tables DB** (MariaDB). Documents DB (MongoDB) does not support CSV imports.
+{% /info %}
+
Appwrite's CSV Import feature allows you to create multiple rows in a table by uploading a single CSV file. This is especially useful for importing existing data, seeding test environments, or migrating from other systems.
This feature is available in both Appwrite Cloud and the self-hosted version.
diff --git a/src/routes/docs/products/databases/databases/+page.markdoc b/src/routes/docs/products/databases/databases/+page.markdoc
index ef98f07201..f8c35175f3 100644
--- a/src/routes/docs/products/databases/databases/+page.markdoc
+++ b/src/routes/docs/products/databases/databases/+page.markdoc
@@ -4,8 +4,11 @@ title: Databases
description: Dive deeper into Appwrite Databases and their configuration. Learn how to create, manage, and optimize multiple databases for your application.
---
Databases are the largest organizational unit in Appwrite.
-Each database contains a group of [tables](/docs/products/databases/tables).
-In future versions, different databases may be backed by a different database technology of your choosing.
+Each database contains a group of [tables](/docs/products/databases/tables) (Tables DB) or [collections](/docs/products/databases/documentsdb/collections) (Documents DB).
+
+{% info title="Terminology mapping" %}
+Code examples on this page use Tables DB (`TablesDB`). For Documents DB, use `DocumentsDB` instead of `TablesDB`.
+{% /info %}
# Create in Console {% #create-in-console %}
The easiest way to create a database using the Appwrite Console.
diff --git a/src/routes/docs/products/databases/documentsdb/atomic-numeric-operations/+page.markdoc b/src/routes/docs/products/databases/documentsdb/atomic-numeric-operations/+page.markdoc
new file mode 100644
index 0000000000..8a9abbe526
--- /dev/null
+++ b/src/routes/docs/products/databases/documentsdb/atomic-numeric-operations/+page.markdoc
@@ -0,0 +1,763 @@
+---
+layout: article
+title: Atomic numeric operations
+description: Safely increment and decrement numeric fields without race conditions. Perfect for counters, quotas, inventory, and usage metrics in high-concurrency applications.
+---
+
+Atomic numeric operations allow you to safely increase or decrease numeric fields without fetching the full document. This eliminates race conditions and reduces bandwidth usage when updating any numeric values that need to be modified atomically, such as counters, scores, balances, and other fast-moving numeric data.
+
+# How atomic operations work {% #how-atomic-operations-work %}
+
+Instead of the traditional read-modify-write pattern, atomic numeric operations use dedicated methods to modify values directly on the server. The server applies the change atomically under concurrency control and returns the new value.
+
+**Traditional approach:**
+1. Fetch document → `{ likes: 42 }`
+2. Update client-side → `likes: 43`
+3. Write back → `{ likes: 43 }`
+
+**Atomic approach:**
+1. Call `incrementDocumentAttribute()` with the attribute name and the value to increment by
+2. Server applies atomically → `likes: 43`
+
+# When to use atomic operations {% #when-to-use-atomic-operations %}
+
+Atomic numeric operations work well for:
+
+- **Social features**: Likes, follows, comment counts
+- **Usage metering**: API credits, storage quotas, request limits
+- **Game state**: Scores, lives, currency, experience points
+- **E-commerce**: Stock counts, inventory levels
+- **Workflow tracking**: Retry counts, progress indicators
+- **Rate limiting**: Request counters, usage tracking
+
+# Perform atomic operations {% #perform-atomic-operations %}
+
+Use the `incrementDocumentAttribute` and `decrementDocumentAttribute` methods to perform atomic numeric operations. The server will apply these changes atomically under concurrency control.
+
+## Increment a field {% #increment-field %}
+
+{% multicode %}
+```client-web
+import { Client, DocumentsDB } from "appwrite";
+
+const client = new Client()
+ .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject(''); // Your project ID
+
+const documentsDB = new DocumentsDB(client);
+
+const result = await documentsDB.incrementDocumentAttribute({
+ databaseId: '',
+ collectionId: '',
+ documentId: '',
+ attribute: 'likes', // attribute
+ value: 1 // value
+});
+```
+```client-flutter
+import 'package:appwrite/appwrite.dart';
+
+final client = Client()
+ .setEndpoint('https://.cloud.appwrite.io/v1')
+ .setProject('');
+
+final documentsDB = DocumentsDB(client);
+
+final document = await documentsDB.incrementDocumentAttribute(
+ databaseId: '',
+ collectionId: '',
+ documentId: '',
+ attribute: 'likes',
+ value: 1
+);
+```
+```client-apple
+import Appwrite
+import AppwriteModels
+
+let client = Client()
+ .setEndpoint("https://.cloud.appwrite.io/v1")
+ .setProject("")
+
+let documentsDB = DocumentsDB(client)
+
+let document = try await documentsDB.incrementDocumentAttribute(
+ databaseId: "",
+ collectionId: "",
+ documentId: "",
+ attribute: "likes",
+ value: 1
+)
+```
+```client-android-kotlin
+import io.appwrite.Client
+import io.appwrite.services.DocumentsDB
+
+val client = Client(applicationContext)
+ .setEndpoint("https://.cloud.appwrite.io/v1")
+ .setProject("")
+
+val documentsDB = DocumentsDB(client)
+
+val document = documentsDB.incrementDocumentAttribute(
+ databaseId = "",
+ collectionId = "",
+ documentId = "",
+ attribute = "likes",
+ value = 1
+)
+```
+```server-nodejs
+const sdk = require('node-appwrite');
+
+const client = new sdk.Client()
+ .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('') // Your project ID
+ .setKey(''); // Your secret API key
+
+const documentsDB = new sdk.DocumentsDB(client);
+
+const result = await documentsDB.incrementDocumentAttribute({
+ databaseId: '',
+ collectionId: '',
+ documentId: '',
+ attribute: 'likes', // attribute
+ value: 1 // value
+});
+```
+```server-python
+from appwrite.client import Client
+from appwrite.services.documents_db import DocumentsDB
+
+client = Client()
+client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint
+client.set_project('') # Your project ID
+client.set_key('') # Your secret API key
+
+documentsDB = DocumentsDB(client)
+
+result = documentsDB.increment_document_attribute(
+ database_id = '',
+ collection_id = '',
+ document_id = '',
+ attribute = 'likes', # attribute
+ value = 1 # value
+)
+```
+```graphql
+mutation {
+ databasesIncrementDocumentAttribute(
+ databaseId: "",
+ collectionId: "",
+ documentId: "",
+ attribute: "likes",
+ value: 1
+ ) {
+ _id
+ _collectionId
+ _databaseId
+ _createdAt
+ _updatedAt
+ _permissions
+ data
+ }
+}
+```
+{% /multicode %}
+
+## Decrement a field {% #decrement-field %}
+
+Use the `decrementDocumentAttribute` method to decrease numeric fields:
+
+{% multicode %}
+```client-web
+import { Client, DocumentsDB } from "appwrite";
+
+const client = new Client()
+ .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject(''); // Your project ID
+
+const documentsDB = new DocumentsDB(client);
+
+const result = await documentsDB.decrementDocumentAttribute({
+ databaseId: '',
+ collectionId: '',
+ documentId: '',
+ attribute: 'credits', // attribute
+ value: 5 // value
+});
+```
+```client-flutter
+import 'package:appwrite/appwrite.dart';
+
+final client = Client()
+ .setEndpoint('https://.cloud.appwrite.io/v1')
+ .setProject('');
+
+final documentsDB = DocumentsDB(client);
+
+final document = await documentsDB.decrementDocumentAttribute(
+ databaseId: '',
+ collectionId: '',
+ documentId: '',
+ attribute: 'credits',
+ value: 5
+);
+```
+```client-apple
+import Appwrite
+import AppwriteModels
+
+let client = Client()
+ .setEndpoint("https://.cloud.appwrite.io/v1")
+ .setProject("")
+
+let documentsDB = DocumentsDB(client)
+
+let document = try await documentsDB.decrementDocumentAttribute(
+ databaseId: "",
+ collectionId: "",
+ documentId: "",
+ attribute: "credits",
+ value: 5
+)
+```
+```client-android-kotlin
+import io.appwrite.Client
+import io.appwrite.services.DocumentsDB
+
+val client = Client(applicationContext)
+ .setEndpoint("https://.cloud.appwrite.io/v1")
+ .setProject("")
+
+val documentsDB = DocumentsDB(client)
+
+val document = documentsDB.decrementDocumentAttribute(
+ databaseId = "",
+ collectionId = "",
+ documentId = "",
+ attribute = "credits",
+ value = 5
+)
+```
+```server-nodejs
+const sdk = require('node-appwrite');
+
+const client = new sdk.Client()
+ .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('') // Your project ID
+ .setKey(''); // Your secret API key
+
+const documentsDB = new sdk.DocumentsDB(client);
+
+const result = await documentsDB.decrementDocumentAttribute({
+ databaseId: '',
+ collectionId: '',
+ documentId: '',
+ attribute: 'credits', // attribute
+ value: 5 // value
+});
+```
+```server-python
+from appwrite.client import Client
+from appwrite.services.documents_db import DocumentsDB
+
+client = Client()
+client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint
+client.set_project('') # Your project ID
+client.set_key('') # Your secret API key
+
+documentsDB = DocumentsDB(client)
+
+result = documentsDB.decrement_document_attribute(
+ database_id = '',
+ collection_id = '',
+ document_id = '',
+ attribute = 'credits', # attribute
+ value = 5 # value
+)
+```
+```graphql
+mutation {
+ databasesDecrementDocumentAttribute(
+ databaseId: "",
+ collectionId: "",
+ documentId: "",
+ attribute: "credits",
+ value: 5
+ ) {
+ _id
+ _collectionId
+ _databaseId
+ _createdAt
+ _updatedAt
+ _permissions
+ data
+ }
+}
+```
+{% /multicode %}
+
+# Set constraints and bounds {% #set-constraints-and-bounds %}
+
+You can set minimum and maximum bounds for individual operations to prevent invalid values. Use the optional `min` and `max` parameters to ensure the final value stays within acceptable limits:
+
+## Example with constraints {% #example-with-constraints %}
+
+{% multicode %}
+```client-web
+// Increment with maximum constraint
+const result = await documentsDB.incrementDocumentAttribute({
+ databaseId: '',
+ collectionId: '',
+ documentId: '',
+ attribute: 'credits', // attribute
+ value: 100, // value
+ max: 1000 // max (optional)
+});
+
+// Decrement with minimum constraint
+const result2 = await documentsDB.decrementDocumentAttribute({
+ databaseId: '',
+ collectionId: '',
+ documentId: '',
+ attribute: 'credits', // attribute
+ value: 50, // value
+ min: 0 // min (optional)
+});
+```
+```client-flutter
+// Increment with maximum constraint
+final document = await documentsDB.incrementDocumentAttribute(
+ databaseId: '',
+ collectionId: '',
+ documentId: '',
+ attribute: 'credits',
+ value: 100,
+ max: 1000
+);
+
+// Decrement with minimum constraint
+final document2 = await documentsDB.decrementDocumentAttribute(
+ databaseId: '',
+ collectionId: '',
+ documentId: '',
+ attribute: 'credits',
+ value: 50,
+ min: 0
+);
+```
+```client-apple
+// Increment with maximum constraint
+let document = try await documentsDB.incrementDocumentAttribute(
+ databaseId: "",
+ collectionId: "",
+ documentId: "",
+ attribute: "credits",
+ value: 100,
+ max: 1000
+)
+
+// Decrement with minimum constraint
+let document2 = try await documentsDB.decrementDocumentAttribute(
+ databaseId: "",
+ collectionId: "",
+ documentId: "",
+ attribute: "credits",
+ value: 50,
+ min: 0
+)
+```
+```client-android-kotlin
+// Increment with maximum constraint
+val document = documentsDB.incrementDocumentAttribute(
+ databaseId = "",
+ collectionId = "",
+ documentId = "",
+ attribute = "credits",
+ value = 100,
+ max = 1000
+)
+
+// Decrement with minimum constraint
+val document2 = documentsDB.decrementDocumentAttribute(
+ databaseId = "",
+ collectionId = "",
+ documentId = "",
+ attribute = "credits",
+ value = 50,
+ min = 0
+)
+```
+```server-nodejs
+// Increment with maximum constraint
+const result = await documentsDB.incrementDocumentAttribute({
+ databaseId: '',
+ collectionId: '',
+ documentId: '',
+ attribute: 'credits', // attribute
+ value: 100, // value
+ max: 1000 // max (optional)
+});
+
+// Decrement with minimum constraint
+const result2 = await documentsDB.decrementDocumentAttribute({
+ databaseId: '',
+ collectionId: '',
+ documentId: '',
+ attribute: 'credits', // attribute
+ value: 50, // value
+ min: 0 // min (optional)
+});
+```
+```server-python
+# Increment with maximum constraint
+result = documentsDB.increment_document_attribute(
+ database_id = '',
+ collection_id = '',
+ document_id = '',
+ attribute = 'credits', # attribute
+ value = 100, # value
+ max = 1000 # max (optional)
+)
+
+# Decrement with minimum constraint
+result2 = documentsDB.decrement_document_attribute(
+ database_id = '',
+ collection_id = '',
+ document_id = '',
+ attribute = 'credits', # attribute
+ value = 50, # value
+ min = 0 # min (optional)
+)
+```
+{% /multicode %}
+
+# Follow best practices {% #follow-best-practices %}
+
+## Use for high-concurrency scenarios {% #use-for-high-concurrency-scenarios %}
+
+Atomic numeric operations are most beneficial when multiple users or processes might update the same numeric field simultaneously.
+
+## Combine with regular updates {% #combine-with-regular-updates %}
+
+For complex updates that include both atomic operations and regular field changes, you'll need to use separate API calls:
+
+{% multicode %}
+```client-web
+// First, increment the likes atomically
+const likeResult = await documentsDB.incrementDocumentAttribute(
+ '',
+ '',
+ '',
+ 'likes', // attribute
+ 1 // value
+);
+
+// Then, update other fields
+const updateResult = await documentsDB.updateDocument(
+ '',
+ '',
+ '',
+ {
+ lastLikedBy: userId,
+ lastLikedAt: new Date().toISOString()
+ }
+);
+```
+```client-flutter
+// First, increment the likes atomically
+final likeResult = await documentsDB.incrementDocumentAttribute(
+ databaseId: '',
+ collectionId: '',
+ documentId: '',
+ attribute: 'likes',
+ value: 1
+);
+
+// Then, update other fields
+final updateResult = await documentsDB.updateDocument(
+ databaseId: '',
+ collectionId: '',
+ documentId: '',
+ data: {
+ 'lastLikedBy': userId,
+ 'lastLikedAt': DateTime.now().toIso8601String()
+ }
+);
+```
+```client-apple
+// First, increment the likes atomically
+let likeResult = try await documentsDB.incrementDocumentAttribute(
+ databaseId: "",
+ collectionId: "",
+ documentId: "",
+ attribute: "likes",
+ value: 1
+)
+
+// Then, update other fields
+let updateResult = try await documentsDB.updateDocument(
+ databaseId: "",
+ collectionId: "",
+ documentId: "",
+ data: [
+ "lastLikedBy": userId,
+ "lastLikedAt": ISO8601DateFormatter().string(from: Date())
+ ]
+)
+```
+```client-android-kotlin
+// First, increment the likes atomically
+val likeResult = documentsDB.incrementDocumentAttribute(
+ databaseId = "",
+ collectionId = "",
+ documentId = "",
+ attribute = "likes",
+ value = 1
+)
+
+// Then, update other fields
+val updateResult = documentsDB.updateDocument(
+ databaseId = "",
+ collectionId = "",
+ documentId = "",
+ data = mapOf(
+ "lastLikedBy" to userId,
+ "lastLikedAt" to Instant.now().toString()
+ )
+)
+```
+```server-nodejs
+// First, increment the likes atomically
+const likeResult = await documentsDB.incrementDocumentAttribute(
+ '',
+ '',
+ '',
+ 'likes', // attribute
+ 1 // value
+);
+
+// Then, update other fields
+const updateResult = await documentsDB.updateDocument(
+ '',
+ '',
+ '',
+ {
+ lastLikedBy: userId,
+ lastLikedAt: new Date().toISOString()
+ }
+);
+```
+```server-python
+# First, increment the likes atomically
+like_result = documentsDB.increment_document_attribute(
+ database_id = '',
+ collection_id = '',
+ document_id = '',
+ attribute = 'likes', # attribute
+ value = 1 # value
+)
+
+# Then, update other fields
+update_result = documentsDB.update_document(
+ database_id = '',
+ collection_id = '',
+ document_id = '',
+ data = {
+ 'lastLikedBy': user_id,
+ 'lastLikedAt': datetime.now().isoformat()
+ }
+)
+```
+{% /multicode %}
+
+# Use transactions {% #use-transactions %}
+
+Atomic numeric operations accept `transactionId`. When provided, increments/decrements are staged and applied on commit.
+
+{% multicode %}
+```client-web
+await documentsDB.incrementDocumentAttribute({
+ databaseId: '',
+ collectionId: '',
+ documentId: '',
+ attribute: 'likes',
+ value: 1,
+ transactionId: ''
+});
+```
+```client-flutter
+await documentsDB.incrementDocumentAttribute(
+ databaseId: '',
+ collectionId: '',
+ documentId: '',
+ attribute: 'likes',
+ value: 1,
+ transactionId: ''
+);
+```
+```client-apple
+try await documentsDB.incrementDocumentAttribute(
+ databaseId: "",
+ collectionId: "",
+ documentId: "",
+ attribute: "likes",
+ value: 1,
+ transactionId: ""
+)
+```
+```client-android-kotlin
+documentsDB.incrementDocumentAttribute(
+ databaseId = "",
+ collectionId = "",
+ documentId = "",
+ attribute = "likes",
+ value = 1,
+ transactionId = ""
+)
+```
+```client-android-java
+documentsDB.incrementDocumentAttribute(
+ "",
+ "",
+ "",
+ "likes",
+ 1,
+ "",
+ new CoroutineCallback<>((result, error) -> {
+ if (error != null) {
+ error.printStackTrace();
+ return null;
+ }
+ System.out.println(result);
+ return null;
+ })
+);
+```
+```client-react-native
+await documentsDB.incrementDocumentAttribute({
+ databaseId: '',
+ collectionId: '',
+ documentId: '',
+ attribute: 'likes',
+ value: 1,
+ transactionId: ''
+});
+```
+```server-nodejs
+await documentsDB.incrementDocumentAttribute({
+ databaseId: '',
+ collectionId: '',
+ documentId: '',
+ attribute: 'likes',
+ value: 1,
+ transactionId: ''
+});
+```
+```server-deno
+await documentsDB.incrementDocumentAttribute({
+ databaseId: '',
+ collectionId: '',
+ documentId: '',
+ attribute: 'likes',
+ value: 1,
+ transactionId: ''
+});
+```
+```server-python
+documentsDB.increment_document_attribute(
+ database_id = '',
+ collection_id = '',
+ document_id = '',
+ attribute = 'likes',
+ value = 1,
+ transaction_id = ''
+)
+```
+```server-php
+$documentsDB->incrementDocumentAttribute(
+ databaseId: '',
+ collectionId: '',
+ documentId: '',
+ attribute: 'likes',
+ value: 1,
+ transactionId: ''
+);
+```
+```server-ruby
+documentsDB.increment_document_attribute(
+ database_id: '',
+ collection_id: '',
+ document_id: '',
+ attribute: 'likes',
+ value: 1,
+ transaction_id: ''
+)
+```
+```server-dotnet
+await documentsDB.IncrementDocumentAttribute(
+ databaseId: "",
+ collectionId: "",
+ documentId: "",
+ attribute: "likes",
+ value: 1,
+ transactionId: ""
+);
+```
+```server-dart
+await documentsDB.incrementDocumentAttribute(
+ databaseId: '',
+ collectionId: '',
+ documentId: '',
+ attribute: 'likes',
+ value: 1,
+ transactionId: ''
+);
+```
+```server-swift
+try await documentsDB.incrementDocumentAttribute(
+ databaseId: "",
+ collectionId: "",
+ documentId: "",
+ attribute: "likes",
+ value: 1,
+ transactionId: ""
+)
+```
+```server-kotlin
+documentsDB.incrementDocumentAttribute(
+ databaseId = "",
+ collectionId = "",
+ documentId = "",
+ attribute = "likes",
+ value = 1,
+ transactionId = ""
+)
+```
+```server-java
+documentsDB.incrementDocumentAttribute(
+ "",
+ "",
+ "",
+ "likes",
+ 1,
+ "",
+ new CoroutineCallback<>((result, error) -> {
+ if (error != null) {
+ error.printStackTrace();
+ return null;
+ }
+ System.out.println(result);
+ return null;
+ })
+);
+```
+{% /multicode %}
+
+## Explore related features
+
+- [Bulk operations](/docs/products/databases/bulk-operations) - Update multiple documents at once
+- [Permissions](/docs/products/databases/permissions) - Control access to documents
+- [Queries](/docs/products/databases/queries) - Find documents to update
+- [Relationships](/docs/products/databases/relationships) - Update related documents
diff --git a/src/routes/docs/products/databases/documentsdb/bulk-operations/+page.markdoc b/src/routes/docs/products/databases/documentsdb/bulk-operations/+page.markdoc
new file mode 100644
index 0000000000..2b96f4166b
--- /dev/null
+++ b/src/routes/docs/products/databases/documentsdb/bulk-operations/+page.markdoc
@@ -0,0 +1,446 @@
+---
+layout: article
+title: Bulk operations
+description: Perform bulk operations on documents within your collections for efficient data handling.
+---
+
+Appwrite Databases supports bulk operations for documents, allowing you to create, update, or delete multiple documents in a single request. This can significantly improve performance for apps as it allows you to reduce the number of API calls needed while working with large data sets.
+
+Bulk **update**, **upsert**, and **delete** operations can only be performed via the server-side SDKs. This restriction ensures that only trusted server environments can perform large-scale data modifications. Bulk **create** (`createDocuments`) can be used from both client and server SDKs.
+
+For client applications that need bulk update, upsert, or delete functionality, consider using [Appwrite Functions](/docs/products/functions) with proper rate limiting and validation.
+
+{% info title="Important notes" %}
+- Bulk operations trigger Functions, Webhooks, or Realtime events for each document manipulated. Rather than a single event for the entire bulk operation, each document generates a separate event on the existing realtime channels for its operation type.
+- Collections that contain relationship attributes are not supported via bulk operations. Use individual document operations for collections with relationships.
+{% /info %}
+
+# Atomic behavior {% #atomic-behavior %}
+
+Bulk operations in Appwrite are **atomic**, meaning they follow an all-or-nothing approach. Either all documents in your bulk request succeed, or all documents fail.
+
+This atomicity ensures:
+- **Data consistency**: Your database remains in a consistent state even if some operations would fail.
+- **Race condition prevention**: Multiple clients can safely perform bulk operations simultaneously.
+- **Simplified error handling**: You only need to handle complete success or complete failure scenarios.
+
+For example, if you attempt to create 100 documents and one fails due to a validation error, none of the 100 documents will be created.
+
+# Plan limits {% #plan-limits %}
+
+Bulk operations have different limits based on your Appwrite plan:
+
+| Plan | Documents per request |
+|------|----------------------|
+| Free | 100 |
+| Pro | 1,000 |
+
+These limits apply to all bulk operations including create, update, upsert, and delete operations. If you need higher limits than what the Pro plan offers, you can [inquire](/contact-us/enterprise) about a custom plan.
+
+# Create documents {% #create-documents %}
+
+You can create multiple documents in a single request using the `createDocuments` method.
+
+{% info title="Custom timestamps" %}
+When creating, updating or upserting in bulk, you can set `$createdAt` and `$updatedAt` for each document in the payload. Values must be ISO 8601 date-time strings. If omitted, Appwrite sets them automatically.
+{% /info %}
+
+{% multicode %}
+```client-web
+import { Client, DocumentsDB, ID } from 'appwrite';
+
+const client = new Client()
+ .setEndpoint('https://.cloud.appwrite.io/v1')
+ .setProject('');
+
+const documentsDB = new DocumentsDB(client);
+
+const result = await documentsDB.createDocuments(
+ '',
+ '',
+ [
+ {
+ $id: ID.unique(),
+ name: 'Document 1'
+ },
+ {
+ $id: ID.unique(),
+ name: 'Document 2'
+ }
+ ]
+);
+```
+
+```server-nodejs
+const sdk = require('node-appwrite');
+
+const client = new sdk.Client()
+ .setEndpoint('https://.cloud.appwrite.io/v1')
+ .setProject('')
+ .setKey('');
+
+const documentsDB = new sdk.DocumentsDB(client);
+
+const result = await documentsDB.createDocuments(
+ '',
+ '',
+ [
+ {
+ $id: sdk.ID.unique(),
+ name: 'Document 1'
+ },
+ {
+ $id: sdk.ID.unique(),
+ name: 'Document 2'
+ }
+ ]
+);
+```
+
+```server-python
+from appwrite.client import Client
+from appwrite.services.documents_db import DocumentsDB
+
+client = Client()
+client.set_endpoint('https://.cloud.appwrite.io/v1')
+client.set_project('')
+client.set_key('')
+
+documentsDB = DocumentsDB(client)
+
+result = documentsDB.create_documents(
+ database_id = '',
+ collection_id = '',
+ documents = [
+ {
+ '$id': appwrite.ID.unique(),
+ 'name': 'Document 1'
+ },
+ {
+ '$id': appwrite.ID.unique(),
+ 'name': 'Document 2'
+ }
+ ]
+)
+```
+{% /multicode %}
+
+# Update documents {% #update-documents %}
+
+{% info title="Permissions required" %}
+You must grant **update** permissions to users at the **collection level** before users can update documents.
+[Learn more about permissions](/docs/products/databases/permissions)
+{% /info %}
+
+You can update multiple documents in a single request using the `updateDocuments` method.
+
+{% multicode %}
+```server-nodejs
+const sdk = require('node-appwrite');
+
+const client = new sdk.Client()
+ .setEndpoint('https://.cloud.appwrite.io/v1')
+ .setProject('')
+ .setKey('');
+
+const documentsDB = new sdk.DocumentsDB(client);
+
+const result = await documentsDB.updateDocuments(
+ '',
+ '',
+ {
+ status: 'published'
+ },
+ [
+ sdk.Query.equal('status', 'draft')
+ ]
+);
+```
+
+```server-python
+from appwrite.client import Client
+from appwrite.services.documents_db import DocumentsDB
+
+client = Client()
+client.set_endpoint('https://.cloud.appwrite.io/v1')
+client.set_project('')
+client.set_key('')
+
+documentsDB = DocumentsDB(client)
+
+result = documentsDB.update_documents(
+ database_id = '',
+ collection_id = '',
+ data = {
+ 'status': 'published'
+ },
+ queries = [
+ Query.equal('status', 'draft')
+ ]
+)
+```
+{% /multicode %}
+
+# Upsert documents {% #upsert-documents %}
+
+{% info title="Permissions required" %}
+You must grant **create** and **update** permissions to users at the **collection level** before users can create documents.
+[Learn more about permissions](/docs/products/databases/permissions)
+{% /info %}
+
+You can upsert multiple documents in a single request using the `upsertDocuments(` method.
+
+{% multicode %}
+```server-nodejs
+const sdk = require('node-appwrite');
+
+const client = new sdk.Client()
+ .setEndpoint('https://.cloud.appwrite.io/v1')
+ .setProject('')
+ .setKey('');
+
+const documentsDB = new sdk.DocumentsDB(client);
+
+const result = await documentsDB.upsertDocuments(
+ '',
+ '',
+ [
+ {
+ $id: sdk.ID.unique(),
+ name: 'New Document 1'
+ },
+ {
+ $id: 'document-id-2', // Existing document ID
+ name: 'New Document 2'
+ }
+ ]
+);
+```
+
+```server-python
+from appwrite.client import Client
+from appwrite.services.documents_db import DocumentsDB
+from appwrite.id import ID
+
+client = Client()
+client.set_endpoint('https://.cloud.appwrite.io/v1')
+client.set_project('')
+client.set_key('')
+
+documentsDB = DocumentsDB(client)
+
+result = documentsDB.upsert_documents(
+ database_id = '',
+ collection_id = '',
+ documents = [
+ {
+ '$id': appwrite.ID.unique(),
+ 'name': 'Document 1'
+ },
+ {
+ '$id': 'document-id-2', # Existing document ID
+ 'name': 'New Document 2'
+ }
+ ]
+)
+```
+{% /multicode %}
+
+# Delete documents {% #delete-documents %}
+
+{% info title="Permissions required" %}
+You must grant **delete** permissions to users at the **collection level** before users can delete documents.
+[Learn more about permissions](/docs/products/databases/permissions)
+{% /info %}
+
+You can delete multiple documents in a single request using the `deleteDocuments` method.
+
+{% multicode %}
+```server-nodejs
+const sdk = require('node-appwrite');
+
+const client = new sdk.Client()
+ .setEndpoint('https://.cloud.appwrite.io/v1')
+ .setProject('')
+ .setKey('');
+
+const documentsDB = new sdk.DocumentsDB(client);
+
+const result = await documentsDB.deleteDocuments(
+ '',
+ '',
+ [
+ sdk.Query.equal('status', 'archived')
+ ]
+);
+```
+
+```server-python
+from appwrite.client import Client
+from appwrite.services.documents_db import DocumentsDB
+from appwrite.query import Query
+
+client = Client()
+client.set_endpoint('https://.cloud.appwrite.io/v1')
+client.set_project('')
+client.set_key('')
+
+documentsDB = DocumentsDB(client)
+
+result = documentsDB.delete_documents(
+ database_id = '',
+ collection_id = '',
+ queries = [
+ Query.equal('status', 'archived')
+ ]
+)
+```
+{% /multicode %}
+
+{% info title="Queries for deletion" %}
+
+When deleting documents, you must specify queries to filter which documents to delete.
+If no queries are provided, all documents in the collection will be deleted.
+[Learn more about queries](/docs/products/databases/queries).
+
+{% /info %}
+
+# Use transactions {% #use-transactions %}
+
+All bulk operations accept `transactionId`. When provided, Appwrite stages the bulk request and applies it on commit. See [Transactions](/docs/products/databases/transactions).
+
+{% multicode %}
+```server-nodejs
+await documentsDB.createDocuments({
+ databaseId: '',
+ collectionId: '',
+ documents: [
+ { $id: sdk.ID.unique(), name: 'One' },
+ { $id: sdk.ID.unique(), name: 'Two' }
+ ],
+ transactionId: ''
+});
+```
+```server-python
+documentsDB.create_documents(
+ database_id = '