Mobil geliştirmede Offset Pagination: nedir ve nasıl uygulanır

Yazar: IT Sectr Yayınlanma: 2026-03-11 Okuma süresi: 10 dk

Offset Pagination — ofset sayfalama — HTTP API üzerinden verilerin sayfa sayfa yüklenmesi yöntemi. İstemci offset (başlangıçtan itibaren ofset) ve limit (sayfa boyutu) parametrelerini gönderir, sunucu offset konumundan itibaren kayıtları döndürür. REST API Tutorial'a göre, bu yaklaşım uygulama basitliği sayesinde RESTful hizmetlerinde yaygın olarak kullanılır. Ancak büyük veri hacimlerinde, istenen konuma kadar tüm tablonun taranması nedeniyle ofset sayfalama performans kaybeder.

Önemli Noktalar

  • Offset Pagination — sunucunun N kaydı atlayıp sonraki M kaydı döndürdüğü bir sayfalama yöntemi.
  • Basitlik uygulaması onu REST API ve mobil istemciler için standart haline getirir.
  • Atlama sorunu — istekler arasında kayıt eklendiğinde kullanıcı kopyaları görür.
  • Veri sıçramaları — kayıt silme işlemi sayfaların kaymasına ve içerik kaybına yol açar.
  • Cursor-based sayfalama, ofset yerine son kayda bir işaretçi kullanarak bu sorunları çözer.

Offset Pagination nedir?

Offset Pagination, istemci isteğinin iki parametre içerdiği bir veri sayfalama yöntemidir: offset (kaç kaydın atlanacağı) ve limit (kaç kaydın döndürüleceği). Sunucu OFFSET ve LIMIT ile bir SQL sorgusu yürütür, belirtilen sayıda satırı atlar ve sabit boyutlu bir sonuç kümesi döndürür.

Yöntem, ilişkisel veritabanlarında sayfa gezintisini düzenlemenin en basit yolu olarak ortaya çıkmış ve REST mimarisinin gelişmesiyle birlikte HTTP API'lerine aktarılmıştır. Offset Pagination sunucuda durum depolaması gerektirmez — her istek bağımsızdır ve sorgu için gerekli tüm bilgileri içerir.

Postman (2025) API tasarım raporuna göre, ofset sayfalama, büyük veri kümelerindeki bilinen performans sınırlamalarına rağmen, genel REST API'lerinin %72'sinde kullanılmakta ve baskın standart haline gelmektedir.

İstek ve yanıt yapısı

Offset Pagination ile tipik bir REST isteği, sorgu parametreleri offset ve limit'i içerir. Yanıt, istenen sayfanın kayıt listesini ve gezinme arayüzü oluşturmak için meta verileri içerir.

limit parametresi döndürülen kayıt sayısını sınırlar ve sunucu ile istemciyi aşırı yükten korur. Veri karmaşıklığına bağlı olarak tipik limit değerleri sayfa başına 10 ila 50 kayıt arasındadır.

kotlin
data class PageRequest(
    val offset: Int,
    val limit: Int
)

data class PageResponse<T>(
    val items: List<T>,
    val total: Int,
    val hasMore: Boolean
)

fun RetrofitApi.fetchPage(request: PageRequest): Call<PageResponse<Item>>

Offset Pagination nasıl çalışır

Offset Pagination, OFFSET ve FETCH NEXT (veya MySQL/SQLite'da LIMIT) yapılarıyla bir SQL sorgusuna dönüştürülür. Veritabanı sunucusu tabloyu tarar, ofsete eşit sayıda satırı atlar ve sonraki limit satırlarını döndürür. Ofset ne kadar büyükse sorgu o kadar uzun sürer.

Performans sorunu, veritabanının doğrudan ofset konumuna atlayamamasından kaynaklanır — önceki tüm satırları okumalı ve atmalıdır. offset = 100000 ve limit = 20'de, DBMS 100.020 satır okur ve yalnızca 20 satır döndürür.

SQL sorgusunun iç yüzü

SQL — sunucunun ofset sayfalama yürüttüğü dil. PostgreSQL ve MySQL LIMIT kullanırken, SQL Server ve Oracle OFFSET...FETCH kullanır. Farklı DBMS'ler bu sorguyu farklı şekilde optimize eder, ancak temel tarama sorunu aynı kalır.

sql
SELECT id, title, created_at
FROM articles
ORDER BY created_at DESC
OFFSET 100000 ROWS
FETCH NEXT 20 ROWS ONLY;

Tutarlılık sorunu

Veri tutarlılığı, dinamik kümelerle çalışırken Offset Pagination'ın ana dezavantajıdır. İki kullanıcı isteği arasında tablonun başına yeni bir kayıt eklenirse, mevcut tüm kayıtlar kayar. Kullanıcı kopyalar veya boşluklar görür.

limit = 20 ile 100 kayıtlık bir tablo düşünelim. Sayfa 1'de kullanıcı 1-20 kayıtlarını görür. Bir yönetici 5 yeni kayıt ekler. Sayfa 2'de kullanıcı beklenen 21-40 yerine 26-45 kayıtlarını görür — 21-25 kayıtları atlanır ve önceki kümedeki 21-25 kayıtları sayfa 1'de tekrarlanır.

Offset vs Cursor-based: yaklaşımların karşılaştırması

Cursor-based sayfalama, geçerli sayfanın son kaydına bir işaretçi kullanan Offset Pagination'a bir alternatiftir. Sayısal bir ofset yerine, istemci alınan son kaydın tanımlayıcısını gönderir ve sunucu ondan sonraki N kaydı döndürür.

Cursor-based yaklaşım tutarlılık sorununu çözer: imleç konumu ekleme veya silme işlemlerinde değişmez çünkü imleç bir konum yerine belirli bir kaydı referans alır. Ancak uygulanması daha karmaşıktır — benzersiz sıralanabilir bir alan (genellikle ID veya zaman damgası) gerektirir.

ParametreOffset PaginationCursor-based Pagination
BasitlikYüksek — iki sayısal parametreOrta — imleç kodlaması gerekli
TutarlılıkDüşük — eklemelerde kopyalarYüksek — imleç değişikliklerden etkilenmez
PerformansBüyük ofsette düşerHer hacimde sabit
Sayfaya atlamaEvet — herhangi bir sayfaya gidilebilirHayır — yalnızca sıralı gezinme
Uygun<10K kayıt tabloları, sayfa numaralı UIAkışlar, sonsuz kaydırma, büyük kümeler

Yaklaşımlar arasındaki seçim, kullanıcının arayüz gereksinimlerine bağlıdır. Sayfa numaraları ve doğrudan atlama ile gezinme gerekiyorsa — Offset Pagination daha basittir. Sonsuz kaydırma veya haber akışları için imleçler tercih edilir.

Keyset sayfalama

Keyset sayfalama, OFFSET yerine WHERE kullanarak benzersiz bir anahtarda filtreleme yapılan cursor-based yaklaşımın bir çeşididir. SQL sorgusu WHERE id > lastId gibi bir koşul kullanır ve veritabanının atılan satırları taramadan bir dizin kullanmasına olanak tanır.

PostgreSQL Wiki'ye göre, keyset sayfalama büyük ofsetlerde ofset sorgularından 100-1000 kat daha hızlı çalışır çünkü dizin taraması tam tablo taramasının yerini alır. Dezavantajı, sıralı gezinme olmadan rastgele bir sayfaya atlayamamasıdır.

Offset Pagination ne zaman kullanılır

Offset Pagination, kullanıcının sayfa numarası arayüzüne ihtiyaç duyduğu küçük ve orta ölçekli veri kümeleri (10.000 kayda kadar) için idealdir. Tipik senaryolar arasında yönetim panelleri, sipariş listeleri ve sayfa tabanlı sayfalama ile filtrelenmiş kataloglar bulunur.

Mobil uygulamalar için, yeni eklemelerin nadir veya imkansız olduğu geçmiş verileri yüklerken ofset sayfalama uygundur — örneğin, kullanıcı sipariş geçmişi, tamamlanmış görev listeleri, işlem arşivleri. Bu senaryolarda tutarlılık sorunu ortaya çıkmaz.

Sosyal medya akışları, yorum listeleri, sohbetler ve sık eklemeli diğer dinamik kümeler için önerilmez. Bu durumlarda, boşluklar ve yinelenen kayıtlar kullanıcı deneyimini bozar ve istemcide ek yineleme önleme mantığı gerektirir.

Karma yaklaşım

Karma sayfalama, offset ve imleci birleştirir: ilk istek başlangıç sayfasını göstermek için offset kullanırken, sonraki istekler sonsuz kaydırma yüklemesi için imleç kullanır. Bu yaklaşım Instagram ve Twitter'da kullanılır; ilk sayfa imleç ile yüklenir, ancak önceki bir görünüme dönerken konumu hesaplamak için offset kullanılır.

Karma bir yaklaşım uygulamak, istemcide kullanıcının sanal konumunu depolamayı ve sunucuda iki sayfalama mekanizmasını koordine etmeyi gerektirir. Instagram Engineering bloguna göre, ekipleri ilk yükleme için offset'in yerini alan ek bir startCursor alanıyla cursor-based sayfalama kullanmaktadır.

Mobil uygulamalarda Offset Pagination

Mobil uygulamalar, Android'de Retrofit/OkHttp ve iOS'ta URLSession/Combine ile birlikte Offset Pagination kullanır. Tipik desen, RecyclerView.OnScrollListener veya UICollectionView önceden getirme yoluyla listenin sonuna kaydırıldığında sonraki sayfayı yüklemektir.

Mobil istemcide ofset sayfalama uygulaması üç bileşen içerir: bir sayfalama yöneticisi (mevcut offset ve hasMore'u depolar), bir liste bağdaştırıcısı (öğeleri ve yükleme göstergesini görüntüler) ve bir depo (istekleri yürütür ve hataları işler). Android Jetpack, hem offset hem de cursor-based sayfalamayı kutudan çıkar çıkmaz destekleyen Paging 3 kütüphanesini sunar.

Paging 3 ile Kotlin'de uygulama

Paging 3, sayfalı veri yüklemesi için bir Android Jetpack kütüphanesidir. Ofset takibi, yükleme durumu yönetimi ve kaydırma sırasında otomatik önceden getirme dahil olmak üzere sayfalama mantığını kapsüller. PagingSource, sonraki ve önceki sayfalar için anahtarlar tanımlar.

kotlin
class OffsetPagingSource(
    private val api: ApiService,
    private val limit: Int = 20
) : PagingSource<Int, Item>() {

    override suspend fun load(
        params: LoadParams<Int>
    ): LoadResult<Int, Item> {
        val offset = params.key ?: 0
        return try {
            val response = api.getItems(offset, limit)
            LoadResult.Page(
                data = response.items,
                prevKey = null,
                nextKey = if (response.hasMore) offset + limit else null
            )
        } catch (e: Exception) {
            LoadResult.Error(e)
        }
    }
}

PagingSource, sayfa gezinmesi için prevKey ve nextKey anahtarlarını tanımlar. Ofset sayfalamada prevKey her zaman null'dur (geçmiş kaydedilmeden önceki sayfaya gidilemez), nextKey ise sunucu hasMore = false döndürene kadar her yüklemede limit kadar artar. Bu, mobil listeler için basit ve öngörülebilir bir modeldir.

Offset Pagination'da yaygın hatalar

Birinci hata — sıralama olmadan kayıt sırasına güvenmek. Offset Pagination, benzersiz bir alanda sabit ORDER BY sıralaması gerektirir. Bu olmadan, DBMS kayıtları rastgele sırada döndürebilir ve bu da sayfalar arasında rastgele kopyalara ve boşluklara yol açar.

İkinci hata — kullanıcı arayüzünde sayfa numarasını hesaplamak için offset kullanmak. page = offset / limit + 1 formülü yalnızca yüklemeler arasında hiçbir kayıt silinmemiş veya eklenmemişse çalışır. Dinamik verilerde sayfa numarası hatalı hale gelir ve kullanıcı yanlış bilgiler görür.

Üçüncü hata — büyük offsetli sorguların zaman aşımlarını göz ardı etmek. 100.000'in üzerinde offsette sorgu onlarca saniye sürebilir, arayüzü bloke edebilir ve sunucu kaynaklarını tüketebilir. API düzeyinde maksimum offset değeri (örneğin 10.000) belirlenmesi ve büyük hacimler için cursor-based sayfalama kullanılması önerilir.

Dördüncü hata — yanıta toplam sayıyı eklememek. Toplam kayıt sayısı olmadan istemci sayfa sayısını görüntüleyemez ve numaralı sayfalama uygulayamaz. Ancak büyük tablolarda COUNT(*) maliyetlidir — 100.000 kaydı aşan kümeler için yaklaşık tahminler kullanın veya maksimum toplam değeri sınırlayın.

Sıkça sorulan sorular

Offset Pagination, Cursor-based'den nasıl farklıdır?

Offset, kayıtları atlamak için sayısal bir ofset kullanırken, cursor önceki sayfanın son kaydına bir işaretçi kullanır. Offset uygulaması daha basittir ancak eklemelerde kopyalar ve büyük ofsetlerde performans kaybı yaşar. Cursor, veri değişikliklerinde kararlıdır.

Offset Pagination ne zaman kötü performans gösterir?

Ofset sayfalama, tam tablo taraması nedeniyle 10.000 kaydın üzerindeki ofsetlerde verimsizdir. Ayrıca istekler arasında yeni kayıtların göründüğü dinamik kümeler (akışlar, sohbetler) için uygun değildir — kullanıcı gezinme sırasında boşluklar ve yinelenen kayıtlar görür.

Offset Pagination için hangi limit idealdir?

İdeal limit, kayıt boyutuna ve ağ hızına bağlıdır — sayfa başına 10 ila 50 öğe. Büyük resimli listeler için limit = 10-15 kullanın; metin verileri için 20-50. İstemcinin, sunucuda maksimum sınırla (genellikle 100) kendi limitini belirlemesine her zaman izin verin.

Offset Pagination'da kopyalarla nasıl başa çıkılır?

Kopyalarla başa çıkmak için benzersiz kimliğe göre istemci tarafında yineleme önleme kullanın, benzersiz bir alanda kararlı sıralama uygulayın veya cursor-based sayfalamaya geçin. Android Paging 3, liste öğelerinin otomatik yineleme önlemesi için key desteği sağlar.

Offset Pagination GraphQL ile kullanılabilir mi?

Evet, GraphQL, Relay spesifikasyonu cursor-based yaklaşımı önermesine rağmen, sorguda offset ve limit argümanları aracılığıyla ofset sayfalamayı destekler. Apollo GraphQL ve Relay kütüphaneleri, otomatik sayfa durumu yönetimi ile ofset sayfalama için yerleşik destek sunar.

Özet

  • Offset Pagination — API'den sayfalı veri yükleme sırasında kayıtları atlamak ve sınırlamak için offset ve limit parametrelerini kullanan bir sayfalama yöntemi.
  • Uygulamanın basitliği ve istek bağımsızlığı, Offset Pagination'ı REST API'lerin %72'si için standart yaklaşım haline getirir (Postman verileri, 2025).
  • 10.000'in üzerindeki offsette hedef konuma kadar tablo taraması nedeniyle performans düşer — veritabanı atılan tüm satırları okur.
  • Tutarlılık sorunu — istekler arasında kayıt ekleme ve silme, sayfa sonuçlarında kopyalara ve boşluklara yol açar.
  • Cursor-based sayfalama, sayısal bir ofset yerine son kayda bir işaretçi kullanarak Offset Pagination sorunlarını çözer.
  • Karma yaklaşım, mobil uygulamalarda sonsuz kaydırma için ilk sayfanın offsetini imleç yüklemesiyle birleştirir.
  • Öneri — 10.000 kayda kadar statik kümeler için Offset Pagination kullanın ve büyük hacimler ile dinamik veriler için imleçlere geçin.

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun