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
327 changes: 326 additions & 1 deletion src/routes/docs/products/databases/pagination/+page.markdoc
Original file line number Diff line number Diff line change
Expand Up @@ -294,4 +294,329 @@ Using offset pagination on large tables and frequently updated tables may result

Cursor pagination should be used for frequently updated tablesDB.
It is best suited for lazy-loaded pages with infinite scrolling.
For example, a feed, comment section, chat history, or high volume datasets.
For example, a feed, comment section, chat history, or high volume datasets.

# Skip totals for faster lists {% #skip-totals %}

By default, list responses include an accurate `total` count. On large tables and filtered queries, calculating totals requires an extra database COUNT which can add latency.

If your UI does not rely on exact totals (for example, infinite scroll or “load more”), you can skip counting totals by passing `total=false` to any list endpoint. The response keeps the same shape and sets `total` to `0` for compatibility.

Recommendations:
- Use with cursor pagination for the best performance and UX.
- Keep the default behavior when you need “N results” or “Page X of Y”.

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

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

const tablesDB = new TablesDB(client);

const page = await tablesDB.listRows({
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
queries: [
Query.limit(25)
],
total: false // Skip computing total count
});
```
```server-nodejs
const sdk = require('node-appwrite');

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

const tablesDB = new sdk.TablesDB(client);

const page = await tablesDB.listRows({
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
queries: [
sdk.Query.limit(25)
],
total: false // Skip computing total count
});
```
```server-python
from appwrite.client import Client
from appwrite.services.tables_db import TablesDB
from appwrite.query import Query

client = Client()
client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1')
client.set_project('<PROJECT_ID>')
client.set_key('<YOUR_API_KEY>')

tables_db = TablesDB(client)

page = tables_db.list_rows(
database_id='<DATABASE_ID>',
table_id='<TABLE_ID>',
queries=[
Query.limit(25)
],
total=False # Skip computing total count
)
```
```server-ruby
require 'appwrite'

client = Appwrite::Client.new
.set_endpoint('https://<REGION>.cloud.appwrite.io/v1')
.set_project('<PROJECT_ID>')
.set_key('<YOUR_API_KEY>')

tables_db = Appwrite::TablesDB.new(client)

page = tables_db.list_rows(
database_id: '<DATABASE_ID>',
table_id: '<TABLE_ID>',
queries: [
Appwrite::Query.limit(25)
],
total: false # Skip computing total count
)
```
```server-deno
import { Client, Query, TablesDB } from "https://deno.land/x/appwrite/mod.ts";

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

const tablesDB = new TablesDB(client);

const page = await tablesDB.listRows({
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
queries: [
Query.limit(25)
],
total: false // Skip computing total count
});
```
```server-php
<?php

use Appwrite\Client;
use Appwrite\Query;
use Appwrite\Services\TablesDB;

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

$tablesDB = new TablesDB($client);

$page = $tablesDB->listRows(
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
queries: [
Query::limit(25)
],
total: false // Skip computing total count
);
```
```server-go
package main

import (
"fmt"
"github.com/appwrite/sdk-for-go/appwrite"
"github.com/appwrite/sdk-for-go/query"
)

func main() {
client := appwrite.NewClient()
client.SetEndpoint("https://<REGION>.cloud.appwrite.io/v1")
client.SetProject("<PROJECT_ID>")
client.SetKey("<YOUR_API_KEY>")

tablesDB := appwrite.NewTablesDB(client)

page, err := tablesDB.ListRows(
"<DATABASE_ID>",
"<TABLE_ID>",
appwrite.WithListRowsQueries([]string{
query.Limit(25)
}),
appwrite.WithListRowsTotal(false), // Skip computing total count
)

if err != nil {
fmt.Println(err)
}
}
```
```server-swift
import Appwrite
import AppwriteModels

func main() async throws {
let client = Client()
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1")
.setProject("<PROJECT_ID>")
.setKey("<YOUR_API_KEY>")

let tablesDB = TablesDB(client)

let page = try await tablesDB.listRows(
databaseId: "<DATABASE_ID>",
tableId: "<TABLE_ID>",
queries: [
Query.limit(25)
],
total: false // Skip computing total count
)
}
```
```server-kotlin
import io.appwrite.Client
import io.appwrite.Query
import io.appwrite.services.TablesDB

suspend fun main() {
val client = Client(applicationContext)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1")
.setProject("<PROJECT_ID>")
.setKey("<YOUR_API_KEY>")

val tablesDB = TablesDB(client)

val page = tablesDB.listRows(
databaseId = "<DATABASE_ID>",
tableId = "<TABLE_ID>",
queries = listOf(
Query.limit(25)
),
total = false // Skip computing total count
)
}
```
```server-java
import io.appwrite.Client;
import io.appwrite.Query;
import io.appwrite.services.TablesDB;

public class Main {
public static void main(String[] args) throws Exception {
Client client = new Client()
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1")
.setProject("<PROJECT_ID>")
.setKey("<YOUR_API_KEY>");

TablesDB tablesDB = new TablesDB(client);

RowList page = tablesDB.listRows(
"<DATABASE_ID>",
"<TABLE_ID>",
Arrays.asList(
Query.limit(25)
),
false // Skip computing total count
);
}
}
```
```client-flutter
import 'package:appwrite/appwrite.dart';

void main() async {
final client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
.setProject('<PROJECT_ID>');

final tablesDB = TablesDB(client);

final page = await tablesDB.listRows(
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
queries: [
Query.limit(25)
],
total: false, // Skip computing total count
);
}
```
```client-apple
import Appwrite
import AppwriteModels

func main() async throws {
let client = Client()
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1")
.setProject("<PROJECT_ID>")

let tablesDB = TablesDB(client)

let page = try await tablesDB.listRows(
databaseId: "<DATABASE_ID>",
tableId: "<TABLE_ID>",
queries: [
Query.limit(25)
],
total: false // Skip computing total count
)
}
```
```client-android-kotlin
import io.appwrite.Client
import io.appwrite.Query
import io.appwrite.services.TablesDB

suspend fun main() {
val client = Client(applicationContext)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1")
.setProject("<PROJECT_ID>")

val tablesDB = TablesDB(client)

val page = tablesDB.listRows(
databaseId = "<DATABASE_ID>",
tableId = "<TABLE_ID>",
queries = listOf(
Query.limit(25)
),
total = false // Skip computing total count
)
}
```
```graphql
query {
tablesListRows(
databaseId: "<DATABASE_ID>",
tableId: "<TABLE_ID>",
queries: ["limit(25)"],
total: false
) {
total
rows {
_id
data
}
}
}
```
```http
GET /v1/tablesdb/<DATABASE_ID>/tables/<TABLE_ID>/rows?total=false HTTP/1.1
Content-Type: application/json
X-Appwrite-Project: <PROJECT_ID>
```
```json
{
"total": 0,
"rows": [
{ "_id": "...", "data": { /* ... */ } }
]
}
```
{% /multicode %}
7 changes: 6 additions & 1 deletion src/routes/docs/products/databases/rows/+page.markdoc
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,19 @@ You must grant _read_ permissions to users at the _table level_ before users can
[Learn more about permissions](#permissions)
{% /info %}

Rows can be retrieved using the [List Row](/docs/references/cloud/client-web/tables#listRows) endpoint.
Rows can be retrieved using the [List rows](/docs/references/cloud/client-web/tables#listRows) endpoint.

Results can be filtered, sorted, and paginated using Appwrite's shared set of query methods.
You can find a full guide on querying in the [Queries Guide](/docs/products/databases/queries).

By default, results are limited to the _first 25 items_.
You can change this through [pagination](/docs/products/databases/pagination).

{% info title="Speed up lists by skipping totals" %}
If your UI doesn't need an exact total, set the `total` flag to `false` on list calls. The response keeps the same shape and sets `total` to `0`.
This reduces latency for large tables and filtered queries. Learn more in [Pagination: Skip totals](/docs/products/databases/pagination#skip-totals).
{% /info %}

{% multicode %}
```client-web
import { Client, Query, TablesDB } from "appwrite";
Expand Down