Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions .optimize-cache.json
Original file line number Diff line number Diff line change
Expand Up @@ -254,11 +254,11 @@
"images/blog/appwrite-pricing-update/one-subscription.png": "70f5e8590a9fa96afb90ec24a20bd94fed8acecd07c2c342e08e0215a7c15773",
"images/blog/appwrite-pricing-update/project.png": "862597aa4be7cb9f4dedebc924432882708ff227ae7c2f73d74c1ef60f60049d",
"images/blog/appwrite-query-api/cover.png": "487c4f1c2d7a4e6c06a66afd5f87e63b5bfaaff34cc091e8ca4d6cc03d0bdbb3",
"images/blog/appwrite-realtime-with-flutter/1.png": "15165041f76b8d59f2f4313519a23d9e1a3820d8e1760b6394971babaa8b9709",
"images/blog/appwrite-realtime-with-flutter/2.png": "44740ca35567eb456c922c1af4a4a44a7e22ff3cd5c53e38e83e32518326561a",
"images/blog/appwrite-realtime-with-flutter/3.png": "c4304f0fa8c92e8a6b473e684139034df94ab2dc7732d1c9dccf9240a712f4f1",
"images/blog/appwrite-realtime-with-flutter/4.png": "ea7d6dd933e62fdbd3b1913ce50de91ef3ddc4173915425d5d4db56cb77aaa70",
"images/blog/appwrite-realtime-with-flutter/5.png": "49fe7599941b7f5702c310047d96ac6f664b498001cdd66a5ac335be96f580c0",
"images/blog/appwrite-realtime-with-flutter/1.png": "33959f454fc5bc7aea12e5eabb1ad909b82f65e4c3fbe8fb53846b4f6363bcd4",
"images/blog/appwrite-realtime-with-flutter/2.png": "eddfd14bcb6ce51fa4fcc402fc0116cd9655ae19f73473af101b74357a1fd454",
"images/blog/appwrite-realtime-with-flutter/3.png": "7c62e1212b7306240cb5b2162b8d323297329d4235a20b2dd7e387a6fef5c966",
"images/blog/appwrite-realtime-with-flutter/4.png": "54c571e40c365197d5cfbfff2231a25f524ed54b5dc3a28649101cfb2fe44b3b",
"images/blog/appwrite-realtime-with-flutter/5.png": "3317eff1dda44327d2eaaaf902d9bd9360576aa46298cc913a78e120f61bb3a7",
"images/blog/appwrite-realtime-with-flutter/cover.png": "99376d2cf9983874f7e9238dee186f5098c9b7a23d6f8ea3550d518580c8bb6e",
"images/blog/appwrite-realtime/cover.png": "db1c1110935b9ad2a5675e80242914ec38e919004011b0e1060c4d8bc93db5d5",
"images/blog/appwrite-server-sdk-vs-client-sdk/cover.png": "3b674e35218dc6f203824b8ee53eb367e79c33755f64a5456f290768ad5db96f",
Expand Down Expand Up @@ -321,6 +321,7 @@
"images/blog/build-fullstack-svelte-appwrite/cover.png": "8546e5be90d6c7492366135c26594c57a9b0164b5cb410a3b6c28b3a5c58ff7a",
"images/blog/build-fullstack-svelte-appwrite/expense-app-final-look.png": "d375e8e6093e58a4d3e687f877c4536e5b753d0b16f5542524501366a65e2564",
"images/blog/build-fullstack-svelte-appwrite/permissions-document-security.png": "2921c151824fe91450f0bf2ac821b90a0ee7b533b6e6dc37d032cea68bcf5fef",
"images/blog/build-fullstack-svelte-appwrite/permissions-row-security.png": "3adc9f04c21a5adc60df15f3b557673f258597b2cea902159f6c147395fd64c8",
"images/blog/build-internal-tools-quickly/cover.png": "e04d776ed2b9e74c485ecef8f77920d9ae92cd4bc6875641b6ccc24e96712130",
"images/blog/build-personal-crm-sveltekit/cover.png": "7249afe9a63373551b51fdcd241fc448a8de30ddf86eb0ca48fc614e1877e074",
"images/blog/build-personal-crm-sveltekit/personal-crm-demo.png": "5cb8dd79c440cec12d28a6637a2e6ac1a8ac8ede790facbdab308fee10c01f9f",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
const QUERY = "Store the user's profile avatar image";

const skills = [
'createDocument',
'createRow',
'uploadFile',
'getUser',
'listFiles',
Expand Down
69 changes: 35 additions & 34 deletions src/routes/blog/post/ai-crystal-ball/+page.markdoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ cover: /images/blog/ai-crystal-ball/cover.png
timeToRead: 9
author: aditya-oberai
category: tutorial
lastUpdated: 2026-04-07
---

Have you ever wondered what you would be doing as a developer 5 years from now? I, for sure, have, which is why recently I developed an AI Crystal Ball to use information from my GitHub account and predict what my destiny as a developer would look like. This project picked up a lot more attention than anticipated as well as a number of requests asking how this project was developed.
Expand All @@ -20,7 +21,7 @@ In order to build this application, we have a few prerequisites. We must set up
- OpenAI API key
- GitHub OAuth app
- Appwrite OAuth adapter for GitHub
- Appwrite collections to store GitHub data and destinies
- Appwrite tables to store GitHub data and destinies

## OpenAI

Expand All @@ -47,7 +48,7 @@ In this app, we primarily need Appwrite for the following:

- Managing GitHub OAuth login
- Saving the information we get from the GitHub API, so we don’t need to call it repeatedly
- Saving developer destinies if a user wants to create a shareable link
- Saving developer destinies in a table if a user wants to create a shareable link

The only prerequisite here was creating an [Appwrite Cloud account](https://cloud.appwrite.io/), followed by creating a new project and adding your hostname as a web app to the project.

Expand All @@ -59,35 +60,35 @@ To implement GitHub OAuth, we must visit the **Auth** page on the Appwrite proje

## Appwrite Database

We must create a database with the ID `crystalball` and two collections with the IDs `githubData` and `destiny` in the Appwrite project with the following details:
We must create a database with the ID `crystalball` and two tables with the IDs `githubData` and `destiny` in the Appwrite project with the following details:

#### The `githubData` collection
#### The `githubData` table

Create the collection and add the following attributes:
Create the table and add the following columns:

| Key | Type | Size | Required | Array |
| --- | --- | --- | --- | --- |
| languages | String | 2000 | - | Yes |
| languages | varchar | 2000 | - | Yes |
| followers | Integer | - | Yes | - |
| following | Integer | - | Yes | - |
| username | String | 255 | Yes | - |
| username | varchar | 255 | Yes | - |

Visit the collection settings, enable **Document security,** and set the following (collection-level) **Permissions**:
Visit the table settings, enable **Row security,** and set the following (table-level) **Permissions**:

| Role | Create | Read | Update | Delete |
| --- | --- | --- | --- | --- |
| Users | Yes | - | - | - |

#### The `destiny` collection
#### The `destiny` table

Create the collection and add the following attributes:
Create the table and add the following columns:

| Key | Type | Size | Required |
| --- | --- | --- | --- |
| destiny | String | 25000 | Yes |
| username | String | 255 | Yes |
| destiny | text | 25000 | Yes |
| username | varchar | 255 | Yes |

Visit the collection settings, enable **Document security,** and set the following (collection-level) **Permissions**:
Visit the table settings, enable **Row security,** and set the following (table-level) **Permissions**:

| Role | Create | Read | Update | Delete |
| --- | --- | --- | --- | --- |
Expand Down Expand Up @@ -123,23 +124,23 @@ Lastly, we must create a `.env` file at the root of the directory and add the fo
PUBLIC_APPWRITE_ENDPOINT=
PUBLIC_APPWRITE_PROJECT_ID=
PUBLIC_APPWRITE_DATABASE_ID=
PUBLIC_APPWRITE_COLLECTION_ID_GITHUBDATA=
PUBLIC_APPWRITE_COLLECTION_ID_DESTINY=
PUBLIC_APPWRITE_TABLE_ID_GITHUBDATA=
PUBLIC_APPWRITE_TABLE_ID_DESTINY=
SECRET_OPENAI_API_KEY=
```

After the environment variables are created, we can set up the Appwrite SDK by creating a file `./src/lib/appwrite.js` and adding the following:

```js
import { Client, Account, Databases, OAuthProvider } from 'appwrite';
import { Client, Account, TablesDB, OAuthProvider } from 'appwrite';
import { env } from '$env/dynamic/public';

const client = new Client()
.setEndpoint(env.PUBLIC_APPWRITE_ENDPOINT)
.setProject(env.PUBLIC_APPWRITE_PROJECT_ID);

export const account = new Account(client);
export const databases = new Databases(client);
export const tablesDB = new TablesDB(client);
export { OAuthProvider };
```

Expand Down Expand Up @@ -272,30 +273,30 @@ At this point, we also want to create our Database library using the Appwrite SD

```js
import { Permission, Role, ID } from 'appwrite';
import { databases } from './appwrite';
import { tablesDB } from './appwrite';
import { env } from '$env/dynamic/public';

const databaseId = env.PUBLIC_APPWRITE_DATABASE_ID;
const githubDataCollectionId = env.PUBLIC_APPWRITE_COLLECTION_ID_GITHUBDATA;
const githubDataTableId = env.PUBLIC_APPWRITE_TABLE_ID_GITHUBDATA;

export const db = {
getUserData: async(documentId) => {
getUserData: async(rowId) => {
try{
return await databases.getDocument({
return await tablesDB.getRow({
databaseId,
collectionId: githubDataCollectionId,
documentId
tableId: githubDataTableId,
rowId
});
} catch(err){
return false;
}
},

addUserData: async(userId, username, followers, following, languages) => {
return await databases.createDocument({
return await tablesDB.createRow({
databaseId,
collectionId: githubDataCollectionId,
documentId: userId,
tableId: githubDataTableId,
rowId: userId,
data: {
username,
followers,
Expand Down Expand Up @@ -504,30 +505,30 @@ Lastly, to share our destiny with the rest of the world, we must create an addit
.
.
.
const destinyCollectionId = env.PUBLIC_APPWRITE_COLLECTION_ID_DESTINY;
const destinyTableId = env.PUBLIC_APPWRITE_TABLE_ID_DESTINY;

export const db = {**
.
.
.
addDestiny: async(username, destiny) => {
return await databases.createDocument({
return await tablesDB.createRow({
databaseId,
collectionId: destinyCollectionId,
documentId: ID.unique(),
tableId: destinyTableId,
rowId: ID.unique(),
data: {
username,
destiny
}
})
},

getDestiny: async(documentId) => {
getDestiny: async(rowId) => {
try{
return await databases.getDocument({
return await tablesDB.getRow({
databaseId,
collectionId: destinyCollectionId,
documentId
tableId: destinyTableId,
rowId
});
} catch(err){
return {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
---
layout: post
title: "Announcing Auto-increment support: Built-in numeric sequencing for your documents"
description: Get reliable, sequential ordering across your collections with fast, indexed auto-increment IDs.
title: "Announcing Auto-increment support: Built-in numeric sequencing for your rows"
description: Get reliable, sequential ordering across your tables with fast, indexed auto-increment IDs.
date: 2025-07-15
lastUpdated: 2026-04-07
cover: /images/blog/announcing-auto-increment-support/cover.png
timeToRead: 5
author: jake-barnby
Expand All @@ -14,11 +15,11 @@ Managing ordered data can often be complex and error-prone, especially when it r

To tackle this issue, we're introducing **Auto-increment support.**

This new feature automatically handles a `$sequence` column within your documents, incrementing reliably with each new insertion. This ensures your data remains ordered and clear without additional manual overhead.
This new feature automatically handles a `$sequence` column within your rows, incrementing reliably with each new insertion. This ensures your data remains ordered and clear without additional manual overhead.

# Automatic, predictable ordering

Previously, maintaining consistent insertion order and generating numeric identifiers required either manual increments, complex logic, or dependence on timestamps, which weren't always accurate or reliable. Appwrite’s new Auto-increment support feature solves these issues seamlessly, providing a built-in numeric identifier that increases predictably with every new document added.
Previously, maintaining consistent insertion order and generating numeric identifiers required either manual increments, complex logic, or dependence on timestamps, which werent always accurate or reliable. Appwrite’s new Auto-increment support feature solves these issues seamlessly, providing a built-in numeric identifier that increases predictably with every new row added.

Whether you're creating paginated data sets, managing invoice numbers, logging activities, or building real-time feeds, Appwrite's Auto-increment support feature offers effortless numeric sequencing. This means less manual work, fewer bugs, and significantly improved reliability.

Expand All @@ -37,21 +38,21 @@ Integrating Auto-increment support into your Appwrite Databases makes your backe

# How it works

For numeric ordering based on insertion order, you can use the `$sequence` field, which Appwrite automatically adds to all documents. This field increments with each new insert.
For numeric ordering based on insertion order, you can use the `$sequence` field, which Appwrite automatically adds to all rows. This field increments with each new insert.


```client-web
import { Client, Databases, Query } from "appwrite";
import { Client, TablesDB, Query } from "appwrite";

const client = new Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
.setProject('<PROJECT_ID>');

const databases = new Databases(client);
const tablesDB = new TablesDB(client);

databases.listDocuments({
tablesDB.listRows({
databaseId: '<DATABASE_ID>',
collectionId: '<COLLECTION_ID>',
tableId: '<TABLE_ID>',
queries: [
Query.orderAsc('$sequence'),
]
Expand Down
31 changes: 16 additions & 15 deletions src/routes/blog/post/announcing-bulk-api/+page.markdoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ layout: post
title: "Announcing Bulk API: Handle heavy data workloads with ease"
description: Perform multiple database operations in a single API call. Enjoy faster writes and better performance for heavy server-side workloads.
date: 2025-07-03
lastUpdated: 2026-04-07
cover: /images/blog/announcing-bulk-api/cover.png
timeToRead: 5
author: jake-barnby
Expand All @@ -14,9 +15,9 @@ We're excited to introduce another Appwrite Databases feature, **Bulk API**. Exp

# Faster development with bulk actions

Previously, writing or modifying large amounts of data in Appwrite Databases required sending one request per document. This method was inefficient, slow, and resource-intensive, especially when dealing with thousands of records.
Previously, writing or modifying large amounts of data in Appwrite Databases required sending one request per row. This method was inefficient, slow, and resource-intensive, especially when dealing with thousands of records.

With the new Bulk API, you can create, update, or delete multiple documents in one go, vastly speeding up your workflows and reducing network overhead.
With the new Bulk API, you can create, update, or delete multiple rows in one go, vastly speeding up your workflows and reducing network overhead.

# Optimized for server-side workloads

Expand All @@ -36,12 +37,12 @@ Bulk operations can only be performed via the server-side SDKs. The client-side

Utilizing the Bulk API is straightforward. You can use it to:

- Create multiple documents in a single request using the `createDocuments` method
- Update multiple documents in a single request using the `updateDocuments` method
- Delete multiple documents in a single request using the `deleteDocuments` method
- Upsert multiple documents in a single request using the `upsertDocuments` method
- Create multiple rows in a single request using the `createRows` method
- Update multiple rows in a single request using the `updateRows` method
- Delete multiple rows in a single request using the `deleteRows` method
- Upsert multiple rows in a single request using the `upsertRows` method

Here is a code example for creating multiple documents in a single request:
Here is a code example for creating multiple rows in a single request:


```server-nodejs
Expand All @@ -52,22 +53,22 @@ const client = new sdk.Client()
.setProject('<PROJECT_ID>')
.setKey('<API_KEY>');

const databases = new sdk.Databases(client);
const tablesDB = new sdk.TablesDB(client);

const result = await databases.createDocuments(
'<DATABASE_ID>',
'<COLLECTION_ID>',
[
const result = await tablesDB.createRows({
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
rows: [
{
$id: sdk.ID.unique(),
name: 'Document 1',
name: 'Row 1',
},
{
$id: sdk.ID.unique(),
name: 'Document 2',
name: 'Row 2',
}
]
);
});
```


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ layout: post
title: Announcing Database Reads and Writes pricing
description: To ensure Appwrite Cloud's sustainability, we are introducing pricing for database read and write operations, effective April 10th, 2025.
date: 2025-03-13
lastUpdated: 2026-04-07
cover: /images/blog/announcing-database-reads-and-writes-pricing/cover.png
timeToRead: 6
author: eldad-fux
Expand Down Expand Up @@ -40,16 +41,16 @@ Database operations in Appwrite are categorized into two types:
## Read operations

Any action that retrieves data from your database, including:
- Fetching documents with `getDocument` or `listDocuments`.
- Fetching rows with `getRow` or `listRows`.

## Write operations

Any action that modifies data in your database, including:
- Creating documents with `createDocument`.
- Updating documents with `updateDocument`.
- Deleting documents with `deleteDocument`.
- Creating rows with `createRow`.
- Updating rows with `updateRow`.
- Deleting rows with `deleteRow`.

Most operations are counted based on the number of documents affected. For example, if you fetch a collection of 50 documents with a single API call, this counts as 50 read operations, not as a single operation. However, if your query returns no documents, it will count as a single operation.
Most operations are counted based on the number of rows affected. For example, if you fetch a table of 50 rows with a single API call, this counts as 50 read operations, not as a single operation. However, if your query returns no rows, it will count as a single operation.

# Your usage

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ timeToRead: 8
author: eldad-fux
category: product, announcement
featured: false
lastUpdated: 2026-04-07
---

After announcing many new products and features during [Init](/init) as part of the 1.5 release, we saw great excitement within the community to get started with the newly presented Appwrite 1.5. Although already available on self-hosted, the new Appwrite products and features were yet to be released to Cloud. Today, we are excited to say the wait is finally over as we announce the release of Appwrite 1.5 to the Cloud.
Expand Down Expand Up @@ -206,9 +207,9 @@ New Database operators `contains` and `or`, providing greater control and flexib
The contains operator is a great addition to the existing text search operators such as startsWith & endsWith, and can be used in combination with these two.

```js
db.listDocuments({
db.listRows({
databaseId: '<DATABASE_ID>',
collectionId: '<COLLECTION_ID>',
tableId: '<TABLE_ID>',
queries: [
Query.contains('content', ['happy', 'love'])
]
Expand All @@ -218,9 +219,9 @@ db.listDocuments({
To use the OR operator pass Query.or([...]) to the queries array and provide at least two queries within the nested array.

```js
db.listDocuments({
db.listRows({
databaseId: '<DATABASE_ID>',
collectionId: '<COLLECTION_ID>',
tableId: '<TABLE_ID>',
queries: [
Query.or([
Query.contains('name','ivy'),
Expand Down
Loading
Loading