Specyfikacja techniczna — marketplace skryptallegro.pl
Framework inc/idx.php + inc/ofidx.php · PHP 8.3 (wersja produkcyjna) · plikowy NoSQL + opcjonalne MongoDB · stan: wdrożone i działające na VPS Forpsi 4-8 (4 vCPU / 8 GB / 80 GB NVMe) — aukcji.com
1. Czym jest system
Serwis ogłoszeniowo-auckcyjny klasy marketplace: zlecenia usługowe (stary
serwis) + pełny moduł przedmiotów (licytacje, Kup teraz, katalog produktów,
magazyny zdalne). Całość działa na plikowym silniku NoSQL własnej
konstrukcji — bez zewnętrznych zależności PHP (bez Composera), z możliwością
przełączenia warstwy indeksu na MongoDB jednym wpisem w configu.
2. Zrealizowane wymagania (co jest i jak działa)
2.1 Silnik indeksu — inc/idx.php + backendy
| Element | Implementacja | Efekt |
| Rekordy aukcji | dane/aukcje/s<i1>/<i2>/a-<id>.txt — 2-poziomowy shard po ID (65 536 katalogów liści) | O(1) odczyt po ID; ~6 tys. plików/katalog przy 400 mln |
| Mety | idx/meta/m-<id%8192>.php (mapa return array() — OPcache trzyma w RAM) + m-*.log ogon JSONL, kompaktowany do .php przy 3000 wierszy + m-*.php.ser (serialize — szybki odczyt bez OPcache) | odczyt met ≈ pamięć; bez OPcache ~2–4× szybciej przez .ser |
| Postingi (odwrócony indeks) | idx/post/<klucz>.log — append +id/-id tombstony, kompaktacja przy 20 000 | koszt zapytania = rozmiar pasujących list, nie bazy |
| Klucze | kat: (każdy prefiks ścieżki), u:, e: EAN, kc: kod prod., t: typ, s: stan, l: kraj[:miasto], w: słowa (tekst+lokalizacja+sprzedawca), p:<sha1> parametry, pin:/pinpod: wyróżnienia, lic:/kup: licytowane/kupione usera | facety, wykluczenia -słowo, EAN, sprzedawca |
| Zapytanie | najmniejsza lista = driver → przecięcia AND / unie OR / NOT → reszta filtrów po metach → sort → strona → pełne rekordy tylko dla wyświetlanych 10 pozycji | typowy listing ~60–150 ms niezależnie od bazy |
| Fast-path | sorty po dacie (id rosnąco): mety ładowane tylko dla strony + pinów; liczba wyników z cache idx/cnt/ TTL 5 min | strona 500 kosztuje jak strona 1 |
| Liczniki kategorii | idx/kat-cnt.json mapa ścieżka→n, różnicowo przy zapisie | drzewo z (x) <5 ms, te same filtry co lista |
| MongoDB | inc/idx-mongo.php — te same kontrakty funkcji; kolekcje aukcje_meta (klucze w xk[] + multikey index) i katcnt; jeden find robi przecięcia; rekordy zostają plikami | auto-przełącznik MONGO_AUTO: przy ≥N aukcji system sam dogrzewa Mongo w tle (dual-write + import partiami, inc/idx-warm.php) i przełącza się bez rebuildu; tryb ręczny = samo MONGO_URI + rebuild; awaria Mongo = czytelny 503 |
| Cache shardów | hierarchia auto: OPcache → APCu/APC w RAM między żądaniami (klucz = plik+mtime+log, sam się unieważnia) → .ser → .php; per request LRU 32 shardy | działa na każdym hostingu, z każdym rozszerzeniem które jest |
2.2 Silnik ofert-zleceń — inc/ofidx.php (nowy, ta sama architektura)
| Osobne drzewo | dane/ofidx/ — 512 shardów met + postingi (id ofert i aukcji z różnych liczników, nie mogą się zderzyć) |
| Klucze | ofkat: prefiksy, ofu: user, oft: zleceniodawca/zleceniobiorca, ofs: status, ofl: kraj[:miasto], ofw: słowa, ofp:1 pilne, ofst: stawka, ofod: od kogo, ofpl: płeć, ofd:demo/real |
| Listing | oferty_kandydaci_meta() — driver po kluczach + oferta_aktywna (okna demo) na metach; liczniki drzewa kategorii na tym samym zbiorze |
| Migracja | pierwszy odczyt importuje stary oferty-indeks.txt → rename .migrated — upgrade bez ręcznego rebuildu |
2.3 Funkcje sprzedażowe
- 5 typów aukcji: licytacja, licytacja+KupTeraz, KupTeraz, licytacja-wielosztukowa, KupTeraz-wielosztukowy
- Licytacja +0,01 zł, cena minimalna, wykup, licytacje per user (posting
lic:)
- KupTeraz wielosztukowy — koszyk, częściowe wykupy, saldo, karty rozliczeniowe
- Koszyk gościa bez logowania: localStorage (tylko id:sztuk) + pływający zwijany widget w prawym górnym rogu na każdej stronie; podgląd pozycji z serwera (świeże ceny/dostępność — klient nie decyduje o niczym); przy logowaniu/rejestracji scalany w koszyk konta (
wroc = powrót do koszyk.php)
- Zniżka czasowa: tabela rozpisana przy wystawieniu, kroki 6 h, zamrożona w ostatnich 6 h — bez crona; historia zakupów pamięta cenę zakupu
- Wyróżnienia:
pin (góra kategorii), pinpod (góra podkategorii), kolor, pogrubienie — ceny z cennika
- Powiązane aukcje sprzedawcy (max 5), warianty „inny model": kolor/wzór (zdjęcie), rozmiar (tekst), lub oba
- Edycja aktywnych/zawieszonych aukcji: opis + własne zdjęcia + powiązane (katalogu nie rusza)
- Zdjęcia: canvas 420×350 webp w locie, max 10, limit MB per user, podmiana/usuwanie/dodawanie zachowujące nazwy; budżety kompresji ustawiane z panelu admina (per-foto 5–2000 kB, suma aukcji do 20 MB — zamiast stałych w kodzie)
- Merchandising strony głównej: sekcje per kategoria (Elektronika: banner + 4 duże + 3 małe kafle; Dom i wyposażenie; Moda) z bannerami
real/kat-bannery/ i linkami do powiązanych usług — widoczność zależna od danych
- EAN + kod producenta → „podobne przedmioty" i Katalog (admin: Przechwytywanie duplikatów po EAN/kodzie/tytule ≥10 grup; przechwycenie aukcji do katalogu; multi-select podmiana zdjęć na katalogowe — link
katalog, uploady kasowane)
- Wygaśnięcie bez crona — lazy-finalizacja przy odczytce (cron opcjonalny)
2.4 Użytkownicy i skala kont
- Konta shardowane
real/uzytkownik/<h0h1>/<hash>/ (~40 tys./katalog przy 10 mln); stary płaski układ migruje przy zapisie
- Indeks email→hash
dane/em/<md5[0..2]>.txt — 4096 map pod lockiem; rejestracja ~ms niezależnie od liczby kont
- Profile, ksywki, saldo, limity zdjęć per user, wiadomości, obserwowane, koszyk, panel sprzedawcy, badge'y, poziomy zaufania (odznaki)
- Indywidualny serwer-magazyn per użytkownik: admin przypisuje kontu pole
serwer (URL do upusc.php na innym serwerze) — od tego momentu zdjęcia + tytuł/opis/parametry aukcji tego usera trafiają na jego magazyn; kategorie, login, ceny i indeks zostają lokalnie. Osobno: nadpis serwer per aukcja i per pozycja katalogowa + migracja lokalny↔zdalny↔inny-zdalny w panelu katalogu
- Sklepy rekomendujące — także na własnym serwerze/domenie usera: sklep w Konto → Sklep (slug, nazwa, klucz API); storefront u nas pod
/sklep/<slug> z filtrem kategorii i wspólnym koszykiem, albo zewnętrzny sklep-proxy.php — jeden plik na hostingu partnera zaciąga ofertę na żywo przez sklep_api (lista/info po kluczu), a KUP TERAZ prowadzi do naszej kasy z atrybucją po hashu. Tryb multi-sklep: klucz MASTER + rewrite = jeden plik obsługuje wszystkie sklepy po slugu z URL. Prowizja stała za sfinalizowaną sprzedaż → saldo poleceń; dzienny raport mailowy
- Oceny sprzedawcy: „poleca %" = pozytywne / (pozytywne + negatywne) × 100; licznik obok loginu — pozytywne zielone, negatywne bordowe
- Odznaka „Pewna wysyłka": nadawanie/odbieranie w Admin → Odznaczenia (flaga na koncie), ikona przy sprzedawcy na karcie aukcji
- Boty demo: użytkownicy, zgłoszenia, zlecenia — harmonogram + pule tekstów per kategoria
2.5 Integralność i bezpieczeństwo
- Atomowe zapisy aukcji:
aukcja_zmien() — flock na 2048 kubełkach dane/alock/ przez cały cykl read→modify→write; licytacje/kupna/koszyk — koniec wyścigów ceny i sztuk
- CSRF: token sesyjny, doklejany przez
api() i do wszystkich form POST; walidacja w ajax.php, admin.php, botach
- Anty-flood: limiter 5 req/s per IP/konto (
inc/antybot.php), ban-panel w adminie
- Limit logowań:
dane/login-fail/ — 10 pudeł/15 min → blokada IP
- Nagłówki: nosniff, SAMEORIGIN, Referrer-Policy, Permissions-Policy (htaccess + fallback PHP)
- Magazyn:
upusc.php + współdzielony klucz mag-klucz.php (nie CSRF — shared secret)
dane/ i .txt zablokowane z WWW (403)
2.6 SEO i UX
- Przyjazne URLe:
/tytul-miasto-panstwo-123 (aukcje), /...-zlecenie-123 (oferty) — slug + id, stały link
sitemap.php: sitemapindex + segmenty po 16 shardów (aukcje p=2..513, oferty p=1000..1031, statyki p=1), cache plikowy 24 h; robots.txt z wpisem Sitemap
- Autocomplete:
idx/ac.json licznik słów tytułów (delta przy zapisie, kompaktacja), endpoint ajax.php?akcja=ac = top-8 słów + pasujące kategorie; dropdown w polu szukania
- Responsive CSS, burger menu, zachowane całej grafiki (
real/lay/, bannery, wzorki)
- Geo: państwa, miasta, +km promień (odległość w metach), miejscowość tekstowa
- Cache przeglądarki: CSS/JS/czcionki rok (wersjonowane
?v=), grafika 7 dni
- PAŃSTWO zapamiętywane cookie; miasto input+datalist
2.7 Operacja i instalacja
przedinstall.php — samodzielna diagnostyka serwera: wersja PHP, mbstring/json/session/pcre/getimagesize+GD, testy zapisu w dane/real/demo, mod_rewrite (LiteSpeed = działa; Nginx = uwaga), memory_limit, OPcache, cache APCu, exec time, upload/post, wolne miejsce, cURL/allow_url_fopen, Mongo URI vs ext. Kolory: czerwony=blokada, pomarańczowy=ostrzeżenie, zielony=ok
install.php — seed admina/kategorii/demo + diagnostyka + auto-konfiguracja: pisze .user.ini (opcache.enable, memory_limit, upload/post, exec_time) i na mod_php dopisuje php_flag/php_value do .htaccess
- Zdrowie systemu w adminie: backend, rozmiar i liczba plików idx/+ofidx/, wolne miejsce (alarm <1 GB), OPcache, data rebuildu — oraz miernik transferu vnStat (dzienny + miesięczny, limit planu 50 TB/mies.); cache 2 min — zero obciążenia strony
- Admin → Kategorie: drill-down (klik = tylko gałąź + breadcrumbs), dodawanie wielu podkategorii naraz (linia = kategoria), zmiana nazwy automatycznie przepisuje slug i migruje aukcje/oferty na nową ścieżkę; ikony kategorii
real/kat-ikony/<slug>.png
- Przebuduj indeks: ofert + aukcyjny — chunkowany z checkpointami (
rebuild-stan.json + offset bajtowy + rebuild.lock): przy limicie 30 s idzie partiami, admin pokazuje postęp z auto-odświeżaniem, a przerwana przebudowa dobija się sama przy kolejnych odwiedzinach (bufory liczników kat-cnt/ac w stanie)
- Magazyny zdalne: indywidualny serwer per użytkownik (pole
serwer na koncie — zdjęcia+treść jego aukcji na jego maszynie), serwer katalogu (zdjęcia+pełny opis, publiczny endpoint ?opis=), nadpis per aukcja — lokalnie tylko metadane do szukania/sortowania; autoryzacja współdzielonym kluczem mag-klucz.php
2.8 Środowisko produkcyjne — wdrożone i zmierzone (aukcji.com)
| Warstwa | Konfiguracja produkcyjna | Wynik |
| Sprzęt/OS | VPS Forpsi 4-8: 4 vCPU, 8 GB RAM, 80 GB NVMe, 1 Gb/s, 50 TB transferu/mies.; Ubuntu 24.04 LTS | 72 GB wolnego, ~5,2 mln inodów (~400–500 tys. aukcji ze zdjęciami) |
| Serwer HTTP | Apache 2.4.58 mpm_event (do 1024 równoległych połączeń, keep-alive 500 req/3 s) + proxy_fcgi; statyki bez PHP | ~8 300 żądań/s plików statycznych (zmierzone) |
| PHP | PHP 8.3 PHP-FPM: pool dynamiczny do ~120 workerów, listen.backlog 4096; OPcache 512 MB / 50 tys. plików; memory_limit 512M; GD+webp; mod_mime_magic (typy MIME dla zdjęć bez rozszerzenia) | ~8 700–9 200 żądań/s index.php przy 100–300 równoległych — zmierzone ab na produkcji, 0 błędów, max 48 ms |
| System | sysctl: somaxconn + syn_backlog 4096, deskryptory ~1 mln | skok kilku tys. jednoczesnych wejść = kolejka, nie błąd 500 |
| Statystyki serwera w adminie | wolne miejsce na dysku (alarm <1 GB), rozmiar + liczba plików idx/ i ofidx/, stan OPcache, data ostatniej przebudowy, transfer dzienny i miesięczny (vnStat na interfejsie, limit 50 TB) | monitoring bez zewnętrznych narzędzi — wszystko w panelu |
| HTTPS/dostęp | Let's Encrypt, przekierowania wszystkich wariantów → https://www.; SFTP/SSH port 22; nosniff, SAMEORIGIN, Referrer-Policy; dane/ zablokowane (403) | canonical https://www.aukcji.com |
3. Wymagania serwerowe / hostingowe
To samo sprawdza przedinstall.php — tu pełna lista z wartościami
„minimalne / zalecane". Czerwone = bez tego nie ruszy, pomarańczowe = ruszy ale gorzej.
3.1 Wymagane (czerwone — bez tego instalacja stoi)
| Wymaganie | Minimum | Zalecane | Po co |
| PHP | 8.0 | 8.3 + PHP-FPM (stan produkcyjny) | składnia, wydajność; brak Composer i zewnętrznych zależności |
| Rozszerzenia | mbstring, json, session, pcre | + openssl, fileinfo | szukajka (mb_*), rekordy, sesje, slugi, tokeny, typy plików |
getimagesize | tak (GD) | pełne GD + webp | rozpoznawanie JPG/PNG/WEBP przy uploadzie |
| Zapis na dysku | realny zapis w dane/, real/, demo/ (test pliku, nie samo is_writable) | — | rekordy, indeksy, zdjęcia, sesje |
memory_limit | 128M (<128M = stop) | 512M przy milionach rekordów | mapy met, przecięcia zbiorów |
| mod_rewrite (Apache) | tak — SEO URLe | — | .htaccess. LiteSpeed czyta .htaccess jak Apache — działa od razu. Ręcznie przepisać trzeba dopiero na Nginx / OpenLiteSpeed (uwaga pomarańczowa) |
3.2 Wydajność (pomarańczowe — ruszy, ale warto)
| Parametr | Minimum rozsądne | Zalecane | Efekt gdy za mało |
| OPcache | włączony (install próbuje .user.ini/php_flag) | memory_consumption=256+ | shardy met w RAM. Bez niego działa — fallback: shardy .ser (unserialize ~2–4× szybciej niż parse .php) + APCu/APC w RAM gdy hosting je ma |
| APCu / APC | nie wymagane | obecne | plan B gdy OPcache off: mety shardów w RAM między żądaniami (klucz z mtime — sam się unieważnia) |
max_execution_time | 60 s | 300 s (rebuild indeksu) | rebuild ma checkpointy — przy 30 s idzie partiami (admin: auto-odświeżanie + dobijanie przy odwiedzinach); dłuższy = szybciej |
upload_max_filesize | 2M | 10M | zdjęcia aukcji/logo/katalog kompresowane w przeglądarce do ~20–200 kB przed wysyłką — limit dotyczy już tylko drobnych uploadów admina |
post_max_size | 8M (0 = bez limitu) | 30M | formularz = tekst + nazwy plików; zdjęcia lecą osobnymi małymi żądaniami AJAX |
| Wolne miejsce | 5 GB | 20 GB+ (fotka ~18 kB × mln aukcji × 10 = ~180 GB) | rekordy+zdjęcia+indeksy; magazyny zdalne odciążają |
cURL lub allow_url_fopen | jedno z dwóch | cURL | wysyłka do magazynów zdalnych (bez tego tylko lokalne) |
| HTTPS | certyfikat (Let's Encrypt) | wymuszony (htaccess już przepisuje) | sesje/hasła, SEO (Google premiuje) |
3.3 Opcjonalne rozszerzenia skali
| Element | Warunek | Co daje |
mongodb ext (pecl) | + działający serwer MongoDB (Atlas/VPS) + MONGO_URI w configu; MONGO_AUTO = próg aukcji | indeks przecina w Mongo zamiast w PHP — setki mln rekordów, odciążony PHP; włącza się automatycznie po przekroczeniu progu aukcji — dogrzewanie w tle z dual-write, przełączenie bez ręcznego rebuildu, postęp widać w adminie („mongo-warm") |
| Serwery-magazyny per użytkownik | upusc.php + ten sam klucz na każdej maszynie; admin wpisuje userowi jego URL | każdy sprzedawca może mieć własny serwer na zdjęcia/treść swoich aukcji — transfer i dysk rozchodzą się po wielu maszynach, indeks zostaje u nas |
| Serwer katalogu | jak wyżej + pole serwer na pozycji katalogowej | katalog: zdjęcia + pełne opisy (endpoint ?opis=), migracja lokalny↔zdalny↔inny-zdalny z admina |
| Sklep na obcym hostingu/domenie | sklep-proxy.php (1 plik, zero zależności) + klucz API z Konto → Sklep; tryb MASTER = wszystkie sklepy po slugu | storefront u partnera — nasza kasa, rozliczenie i atrybucja sprzedaży; dowolna liczba sklepów poza naszą infrastrukturą |
| CDN (Cloudflare/CloudFront) | DNS przed domeną | cache HTML/obrazków na wejściu, WAF/DDoS |
3.4 Prognoza przepustowości (ile userów naraz, dziennie, miesięcznie)
„Użytkownik dziennie" = unikalny odwiedzający przy ~10 odsłonach/wizytę
(~30% powracających); „miesięcznie" = z puli dzienni×30 po korekcie powtórek.
Liczby szacunkowe — wyjdą z logów po starcie.
| Konfiguracja | Żądań/s | Online naraz | Użytk./dzień | Użytk./mies. | Baza komfortowa | Wartość skryptu* |
| Shared PHP 8.x + OPcache (LiteSpeed/Apache) | ~30–80 | ~800–2 500 | ~10–30 tys. | ~250–800 tys. | setki tys. aukcji | ~400–650 tys. zł |
| ▶ VPS 4 vCPU / 8 GB, PHP 8.3 PHP-FPM + OPcache — NASZA OBECNA WERSJA | ~9 000 zmierzone (ab, localhost); ~1 500–3 000 realnie przez internet | ~15 000–45 000 | ~50–150 tys. | ~1,5–4 mln | miliony aukcji | ~500–800 tys. zł |
| ▶ VPS + Mongo (indeks poza PHP) — NASZA NASTĘPNA WERSJA, włączy się AUTO przy progu aukcji min. 100 000 | ~2 000–4 000 | ~30 000–60 000 | ~100–300 tys. | ~3–8 mln | dziesiątki mln | ~600–900 tys. zł |
| + page-cache anonimów + CDN (do dodania) | ~10 000+ | ~100 000+ | ~300 tys.–1 mln | ~8–20 mln | popularne strony z cache | ~700–950 tys. zł |
| Allegro (dane publiczne) | ~2–20 tys. req/s (szczyt) | ~0,5–2 mln | ~5–8 mln | ~20+ mln | ~200+ mln ofert | ~30–40 mld zł (kapitalizacja) |
Sufit to CPU PHP, nie łącze — port 10 Gbps przeniósłby ~10–25 tys.
odsłon/s, czyli sieć przestaje być tematem długo przed procesorem.
Limit antybot 5 req/s jest per IP — boty nie zajmują przepustowości innych.
Wartości produkcyjne nie są szacunkiem — zmierzone Apache Bench na żywym VPS:
~9 200 żądań/s na index.php przy 300 równoległych (0 błędów); realny sufit
przez internet (TLS+latency) ~1 500–3 000 żądań/s.
*„Wartość skryptu" = szacunkowy koszt wykonania równoważnego
rozwiązania u software house/agencji (lata-praca inżynierów), nie wycena
gotowej firmy — serwisu bez ruchu i marki nikt tyle nie zapłaci. Allegro
dla skali: tysiące serwerów, własne DC, setki inżynierów — nasz wiersz
wyżej pokazuje, że ta sama klasa produktu działa na 1 maszynie.
Wycena rozwiązania (stan produkcyjny)
| Składowa | Zakres prac | Koszt rynkowy* |
| Silnik indeksu NoSQL (odwrócony indeks, tombstony, kompaktacja, facety, liczniki, sitemap, autocomplete) | ~12–18 mies. inż. | ~200–350 tys. zł |
| Backend podmienny MongoDB + atomowe zapisy (flock-shardy) + cache wielowarstwowy (OPcache→APCu→.ser) | ~4–6 mies. inż. | ~80–120 tys. zł |
| Funkcje marketplace: 5 typów aukcji, KupTeraz-wielosztuki, koszyk gościa, katalog EAN + przechwytywanie, warianty, wyróżnienia, zniżki czasowe | ~10–14 mies. inż. | ~180–280 tys. zł |
| Konta/użytkownicy: shardowane rekordy, saldo/rozliczenia, odznaki (poziomy + „Pewna wysyłka"), oceny, wiadomości, limity per user | ~4–6 mies. inż. | ~80–120 tys. zł |
| Magazyny zdalne (serwer per user / per aukcja / katalog, migracje, publiczny endpoint opisów) | ~2–3 mies. inż. | ~40–70 tys. zł |
Sklepy rekomendujące (storefront sklep.php + zewnętrzny sklep-proxy.php, klucze API/MASTER, atrybucja i prowizje) | ~2–3 mies. inż. | ~40–60 tys. zł |
| Panel admina: kategorie (drill-down, bulk, slug+migracja), użytkownicy, cennik, odznaki, statystyki serwera (dysk, indeksy, OPcache, transfer vnStat dzienny/miesięczny), rebuild chunkowany | ~3–5 mies. inż. | ~60–100 tys. zł |
Instalator + diagnostyka (install.php/przedinstall.php, auto-.user.ini) + konfiguracja produkcyjna (PHP-FPM/mpm_event/sysctl) | ~1–2 mies. inż. | ~20–40 tys. zł |
| RAZEM | ~38–57 mies. inżynierskich | ~700 tys. – 1,14 mln zł |
*Wycena wg stawek agencji PL (~15–20 tys. zł/mies. inż.).
To koszt odtworzenia równoważnego systemu — realna cena sprzedaży
licencji/serwisu zależy od ruchu, marki i danych, nie od kosztu produkcji.
3.5 Szacunkowy rozkład ruchu po kategoriach głównych
Szacunek wg wzorców OLX/Allegro (portal ogłoszeniowo-sprzedażowy, PL) —
do planowania shardingu „serwer na kategorię". Liczby realne wyjdą dopiero
z logów i dane/idx/kat-cnt.json; kolumna „serwerów" pokazuje,
ile maszyn przypadłoby na kategorię przy farmie 20 sztuk.
| Kategoria (slug) | Szac. udział ruchu | Serwerów /20 | Uwaga |
| motoryzacja | ~35–45% | 7–9 | zdecydowany lider — części samochodowe, auta, opony. Jedna maszyna jej nie udźwignie — trzeba sub-sharda po hashu ID wewnątrz kategorii |
| elektronika | ~10–14% | 2–3 | telefony, laptopy — druga pod względem ruchu i liczby ofert |
| moda | ~7–10% | 2 | odzież/obuwie — dużo ofert, krótki cykl życia |
| nieruchomosci | ~5–8% | 1–2 | duży ruch wyszukiwań, mało ofert, długie sesje |
| dom-i-wyposazenie | ~5–7% | 1 | meble, AGD — stabilny ruch |
| zlecenia | ~4–8%* | 1–2 | *profil serwisu — jeśli marka stoi na zleceniach, udział rośnie do 15–30% |
| zdrowie + uroda | ~4–6% | 1 | kosmetyki/suplementy — wysoka rotacja ofert |
| dziecko | ~3–5% | 1 | wózki, ubranka — lojalni powracający |
| ogrod | ~2–4% | wspólny | mocno sezonowa (wiosna ×3) |
| kultura + rozrywka | ~2–4% | wspólny | książki, gry, multimedia |
| turystyka | ~2–3% | wspólny | sezonowa |
| wirtualne | ~1–3% | wspólny | konta, klucze, e-booki |
| uslugi | ~1–3% | wspólny | przedmiotowa kategoria usług (nie mylić z „zlecenia") |
| kolekcje-i-sztuka | ~1% | wspólny | nisha, ale wysoka wartość transakcji |
| bilety-i-doladowania | <1% | wspólny | spike'i przy wydarzeniach |
| spozywcze | <1% | wspólny | — |
| pozostale | <1% | wspólny | worek resztkowy |
Wniosek dla architektury 20-serwerowej: podział „1 serwer =
1 kategoria" marnuje maszyny — ~9 kategorii daje łącznie <5% ruchu.
Optymalnie: motoryzacja na kilku maszynach (sub-shard po id % n),
elektronika/moda na osobnych, a ~10 zimnych kategorii na jednym wspólnym.
Realny rozkład mierzy się z liczników kat-cnt.json (oferty)
i logów HTTP (odsłony) — procenty powyżej to punkt startowy, nie fakt.
4. Porównanie z Allegro
| Obszar | Nasz silnik | Allegro | Ocena |
| Wyszukiwanie | odwrócony indeks w: (postingi/Mongo xk[]) | Elasticsearch, klastry | ta sama idea, uczciwa implementacja |
| Kategorie dowolnej głębokości + liczniki | tak — prefiksy kat:, kat-cnt różnicowo | tak | pełne |
| Facety/parametry | p: postingi, OR w parametrze | tak | pełne |
Wykluczenia -słowo | NOT po postingach | tak | pełne |
| Sprzedawca w szukajce | w blobie szuk | tak | pełne |
| EAN/kod/katalog produktów | dokładne e:/kc: + własny Katalog + Przechwytywanie | Katalog Produktów | pełne funkcjonalnie |
| Licytacje + KupTeraz + wielosztuki | 5 typów, atomowe zapisy | tak | pełne |
| Wyróżnienia/promowane | pin/pinpod/kolor/pogrub | Promowane | pełne |
| Lokalizacja + promień | kraj/miasto/+km geo | tak | pełne |
| Ceny promocyjne w czasie | tabela 6 h, zamrożenie końcówki | Strefa okazji | pełne (mechanika prostsza) |
| Wygaśnięcie bez crona | lazy przy odczycie | schedulery | pełne |
| Magazyny zdalne treści/zdjęć | serwery A/B przez upusc.php, linki prosto do przeglądarki | CDN własny | gotowe (to już jest!) |
| Paginacja | 10/strona, koszt ~stały ze stroną | 60/strona + infinite scroll | pełne |
| Wiadomości/koszyk/saldo/prowizje/rozliczenia | tak, własne karty; koszyk też dla gościa (localStorage + widget, scalany przy logowaniu) | tak | pełne |
| Autocomplete | słowa tytułów + kategorie (ac.json) | tak, ML | jest — bez ML/korekty |
| Ranking trafności (BM25) | sort tylko po polach (data/cena/koniec/sprzedane) | trafność + CTR + ML | brak |
| Analiza języka | normalizacja + podciąg; bez stemmingu/odmian/synonimów/literówek | „czy chodziło Ci o…", odmiany | brak |
| Personalizacja/rekomendacje | nie | ranking pod użytkownika, ML | brak |
| Płatności (bramka, escrow, zwroty kupującego) | saldo wewnętrzne, brak bramki | Allegro Pay, Ochrona Kupujących | brak |
| Zwroty/reklamacje/ochrona kupującego | proste karty rozliczeniowe | pełny proces | szkielet |
| API publiczne (REST) | tylko wewnętrzne ajax.php | Allegro REST API | brak |
| Multi-DC/replikacja/failover | 1 serwer + magazyny treści | klastry, replikacja | infrastruktura |
| Aplikacja mobilna/PWA/push | responsive WWW | apki + push | brak |
| Odporność DDoS/WAF | antybot 5 req/s per IP | systemy dedykowane | podstawowy |
| Testy automatyczne/monitoring/CI-CD | brak (review + przedinstall) | pełne | brak |
| Koszt uruchomienia | 1 hosting/VPS | centra danych, zespoły | nasza przewaga |
4.1 Skala — ilu użytkowników obsłuży skrypt PHP 8.3 bez zaplecza serwerowni
Uczciwe porównanie: nasz silnik na jednym VPS-ie (zero własnej
infrastruktury) vs Allegro na tysiącach serwerów.
„Użytkownik dziennie/miesięcznie" jak w 3.4 (~10 odsłon na wizytę).
| Środowisko | Użytkowników dziennie | Użytkowników miesięcznie | Uwaga |
| Nasz skrypt — shared PHP 8.x + OPcache | ~10–30 tys. | ~250–800 tys. | 1 hosting za kilka zł/mies.; shardy + postingi robią całą robotę |
| Nasz skrypt — VPS PHP 8.3 PHP-FPM + OPcache (stan produkcyjny aukcji.com) | ~50–150 tys. | ~1,5–4 mln | 1 maszyna za ~50 zł/mies.; zmierzone ~9 000 żądań/s — wciąż brak „serwerowni" |
| Nasz skrypt — VPS + MongoDB (indeks poza PHP) | ~100–300 tys. | ~3–8 mln | przełącznik w configu, bez zmiany kodu stron |
| Nasz skrypt — + page-cache anonimów + CDN | ~300 tys.–1 mln | ~8–20 mln | 90%+ odsłon to anonimowi czytający — cache zdejmuje je z PHP |
| Allegro (dane publiczne) | ~5–8 mln | ~20+ mln | tysiące serwerów, własne DC, setki inżynierów |
Czytaj uczciwie: różnica nasz-vs-Allegro to ~1–2 rzędy wielkości
na jednej maszynie, a nie tysiące ×. Per-serwer Allegro też serwuje
dziesiątki tys. userów dziennie — po prostu ma ich tysiące maszyn i klaster
płatności/wyszukiwania. Nasz zmierzony sufit na jednym VPS-ie (miliony
użytkowników miesięcznie) to skala dużego polskiego portalu — wystarczająca,
żeby serwis „żył" i zarabiał. Kolejne mnożniki bez zmiany kodu:
MongoDB (~2–3×) → page-cache+CDN (~5–10×) — w tej kolejności, jak ruch rośnie.
5. Czego brakuje — POZA serwerownią (ta już jest: treść/zdjęcia na zewnątrz)
Podział danych na zewnętrzne dyski jest już wdrożony (magazyny A/B). Poniżej to, co jeszcze realnie blokuje poziom „dużego portalu":
Priorytet wysoki — zanim duży ruch
- Cache całych stron listingów dla anonimów —
dane/page/: ten sam URL u wielu = 1 render/60 s zamiast N (realny mnożnik 10–50× użytkowników naraz; bez niego shared kończy się przy ~10–15 odsłonach/s).
- Weryfikacja po zmianach — silnik działa produkcyjnie na PHP 8.3 + PHP-FPM (aukcji.com); kolejne edycje kodu warto przelecieć
php -l po deployu.
- Mailer kolejkowy —
wyslij_mail synchronicznie = czekanie usera; kolejka dane/mail/ + flush (cron/odchodzące).
- Próg „za dużo wyników" dla niezalogowanych — listy ogromne bez filtra (crawler): służ cache top-N zamiast pełnego liczenia.
- Backup/eksport — jeden skrypt pakujący
dane/+real/+demo/ + przywracanie (dziś ręczne).
- Sesje poza filesystemem — przy 2+ serwerach PHP sesje muszą być współdzielone (plik sieciowy / Mongo / sticky sessions na LB).
- CSP — nagłówki już są, ale Content-Security-Policy wymagałby wyniesienia inline
onclick/<script> (dużo refaktoryzacji).
Skala / jakość wyszukiwania
- Meilisearch/OpenSearch jako backend
idx — kontrakty funkcji już są (to 3rd backend, nie przepisanie): ranking BM25, stemming, „czy chodziło Ci o…", synonimy, autocomplete ML — zamyka lukę jakościową vs Allegro.
- Ranking trafności — dziś sort po polach; przy przejściu na Meili: trafność + boost sprzedawcy/dostępności.
- Popularyzacja — licznik wyświetleń/kliknięć aukcji → „popularność" jako sort i sygnał.
- Full-CDN — Cloudflare/CloudFront przed PHP (cache HTML + obrazki + WAF/DDoS na wejściu).
- Rekordy w Mongo — przy setkach mln: pełne rekordy do kolekcji (dziś tylko mety); pliki zostają źródłem importu.
Funkcje produktowe (luka vs Allegro)
- Płatności — bramka (Przelewy24/TPay/Stripe), prowizje, escrow/Ochrona Kupujących; dziś saldo = zaufanie.
- Proces zwrotów/reklamacji — statusy, terminy, mediacje.
- API publiczne — REST dla integracji/sprzedawców hurtowych (klucze API per user).
- PWA/push — powiadomienia o licytacji/sprzedaży, „zainstaluj na telefonie".
- 2FA + CAPTCHA — rejestracja/logowanie przy dużych botach.
- RODO — eksport danych usera, kasowanie konta, zgody, regulamin/cookies.
- Faktury/raporty sprzedawcy — CSV, zestawienia prowizji.
- Multijęzyk/wielowalutowość — UI PL-only dziś.
- Wersjonowanie zdjęć — podmiana pod tą samą nazwą = cache 7 dni widzi stare (rozwiązać
?v=mtime albo hash w nazwie).
Operacyjne
- Logi/obserwowalność — zliczanie 5xx/wolnych zapytań, alert przy >X ms.
- Testy — smoke-tests krytycznych ścieżek (wystaw→szukaj→licytuj→kup) uruchamiane po deployu.
- Rate-limit globalny — oprócz per-IP: sufit całkowity (DDoS rozproszony nie siedzi na jednym IP).
- Kolejka zadań ciężkich — przechwytywanie masowe, regen sitemapy, kompresje — do workera zamiast requestu admina.
- Geo-mapy rosnące — miasta aktualizowalne bez wydania.
6. Uczciwe granice:
Jest: produkcyjny marketplace w 80% aukcyjnym jak Allegro, wieloserwerowy z prawdziwym silnikiem
indeksowym — setki miliony rekordów, miliony użytkowników, magazyny
zdalne treści/zdjęć, przełącznik na MongoDB bez zmiany kodu stron,
skalowanie horyzontalne (stateless, rekordy/indeksy rozdzielone).
Nie jest: klastrem Allegro — czyli nie jest podzielony na działów rozłożonych na różne serwery zdalne, bez replikacji multi-DC, rankingu ML,
płatności/escrow, aplikacji mobilnej i API publicznego.
Do poziomu „Allegro" brakuje warstwy biznesowo-prawnej i operacyjnej (monitoring, testy, CDN, replikacja) — nie silnika.