Skip to content

Listing Performance Analysis

Date: 2026-01-14 Analysis Period: 2024-01-01 onwards (last 3 months for decay analysis)

This analysis covers three key aspects of listing performance:

  1. Time on Market - How long listings take to close by category/city
  2. View Decay - How views decrease as listings age
  3. Contact Conversion Decay - How view-to-contact rates change over time
MetricFinding
Time on MarketImproved 50-60% from early 2024 to late 2025
View Decay75% drop by Day 90, Day 2 is peak
Conversion DecayDrops from 8.5% to 5.2% (-39%) over 90 days
Critical WindowFirst 2 weeks generate ~50% of all contacts

Time on market measures days from published_at to close_time for listings that have been closed.

CategoryClosedMedianP25P75P90
Room for Rent4,59427880145
Big Flat for Rent17,791341470121
Apartment for Rent166,552391582144
Villa for Rent23,256461798159
Land for Sale68,0118933148235
Big Flat for Sale20,6238837149235
Villa for Sale75,8648837155249
Apartment for Sale68,13010453180269

Insight: Rentals move 2-3x faster than sales

CityClosedMedianP25P75
الرياض (Riyadh)302,7015319111
الظهران (Dhahran)2,6385823117
الهفوف (Hofuf)4,2086925127
جدة (Jeddah)72,5247630143
الدمام (Dammam)23,3527828151
مكة المكرمة (Makkah)8,7879435167

Insight: Riyadh is the fastest market

Apartment for Rent (Median Days by Cohort)

Section titled “Apartment for Rent (Median Days by Cohort)”
CohortRiyadhJeddahDammam
Jan 2024516257
Jul 2024393933
Jan 2025333733
Oct 2025323530

Trend: Convergence to ~30-35 days across all cities

CohortRiyadhJeddahDammam
Jan 2024108152141
Jul 202494142164
Jan 2025186021
Oct 2025524930

Trend: Major improvement from 108-152 days to 30-52 days

SELECT
c.name_en AS category,
COUNT(*) AS closed_listings,
ROUND(AVG((l.close_time - l.published_at) / 86400), 1) AS avg_days,
ROUND(
median ((l.close_time - l.published_at) / 86400),
1
) AS median_days,
ROUND(
quantile (0.25) ((l.close_time - l.published_at) / 86400),
1
) AS p25_days,
ROUND(
quantile (0.75) ((l.close_time - l.published_at) / 86400),
1
) AS p75_days,
ROUND(
quantile (0.90) ((l.close_time - l.published_at) / 86400),
1
) AS p90_days
FROM
sadb_listings l FINAL
JOIN sadb_categories c FINAL ON l.category = c.category_id
WHERE
l.close_time > l.published_at
AND l.published_at > 0
AND l._peerdb_is_deleted = 0
AND (l.close_time - l.published_at) / 86400 BETWEEN 1 AND 730
AND toDate (l.published_at) >= '2024-01-01'
GROUP BY
c.name_en
HAVING
closed_listings >= 100
ORDER BY
closed_listings DESC
SELECT
d.city_name,
COUNT(*) AS closed_listings,
ROUND(AVG((l.close_time - l.published_at) / 86400), 1) AS avg_days,
ROUND(
median ((l.close_time - l.published_at) / 86400),
1
) AS median_days,
ROUND(
quantile (0.25) ((l.close_time - l.published_at) / 86400),
1
) AS p25_days,
ROUND(
quantile (0.75) ((l.close_time - l.published_at) / 86400),
1
) AS p75_days
FROM
sadb_listings l FINAL
JOIN sadb_districts d FINAL ON l.district_id = d.district_id
WHERE
l.close_time > l.published_at
AND l.published_at > 0
AND l._peerdb_is_deleted = 0
AND (l.close_time - l.published_at) / 86400 BETWEEN 1 AND 730
AND toDate (l.published_at) >= '2024-01-01'
GROUP BY
d.city_name
HAVING
closed_listings >= 1000
ORDER BY
closed_listings DESC

Query: Monthly Cohort Analysis by Category + City

Section titled “Query: Monthly Cohort Analysis by Category + City”
SELECT
toStartOfMonth (toDate (l.published_at)) AS cohort_month,
c.name_en AS category,
d.city_name,
COUNT(*) AS closed_listings,
ROUND(
median ((l.close_time - l.published_at) / 86400),
1
) AS median_days
FROM
sadb_listings l FINAL
JOIN sadb_categories c FINAL ON l.category = c.category_id
JOIN sadb_districts d FINAL ON l.district_id = d.district_id
WHERE
l.close_time > l.published_at
AND l.published_at > 0
AND l._peerdb_is_deleted = 0
AND (l.close_time - l.published_at) / 86400 BETWEEN 1 AND 365
AND toDate (l.published_at) >= '2024-01-01'
AND c.name_en = 'Apartment for Rent'
AND d.city_name IN ('الرياض', 'جدة', 'الدمام')
GROUP BY
cohort_month,
c.name_en,
d.city_name
HAVING
closed_listings >= 50
ORDER BY
d.city_name,
cohort_month

Views decrease significantly as listings age. Day 2 is typically the peak (not Day 1, due to indexing delays).

Listing AgeAvg ViewsMedian Views% of Peak
Day 128.91873%
Day 239.625100%
Day 333.72185%
Day 726.81668%
Day 1421.71355%
Day 3017.21043%
Day 6012.3731%
Day 909.6524%
CategoryWeek 1Week 2Wk 3-4Mo 2Mo 3Decay
Apartment Rent39.829.924.519.816.8—58%
Villa Rent25.118.314.911.710.2—59%
Villa Sale20.414.812.310.68.6—58%
Land Sale11.37.56.04.94.0—65%
Apartment Sale11.28.98.06.04.7—58%
CityWeek 1Week 2Wk 3-4Mo 2Mo 3Decay
الدمام43.532.426.218.514.7—66%
الرياض31.723.319.014.711.4—64%
جدة27.221.017.513.510.6—61%
مكة23.919.716.612.47.2—70%
SELECT
s.day_time - toInt32 (l.published_at / 86400) AS listing_age_days,
COUNT(DISTINCT s.id) AS listings_count,
SUM(s.views) AS total_views,
ROUND(AVG(s.views), 2) AS avg_views_per_listing,
ROUND(median (s.views), 1) AS median_views
FROM
sadb_stats_listings_stats s FINAL
JOIN sadb_listings l FINAL ON s.id = l.id
WHERE
toDate (s.day_time) >= today () - INTERVAL 3 MONTH
AND l.published_at > 0
AND s.day_time >= toInt32 (l.published_at / 86400)
AND l._peerdb_is_deleted = 0
AND l.status = 1
AND (s.day_time - toInt32 (l.published_at / 86400)) BETWEEN 0 AND 90
GROUP BY
listing_age_days
ORDER BY
listing_age_days
SELECT
c.name_en AS category,
CASE
WHEN listing_age_days BETWEEN 0 AND 7 THEN '1. Week 1'
WHEN listing_age_days BETWEEN 8 AND 14 THEN '2. Week 2'
WHEN listing_age_days BETWEEN 15 AND 30 THEN '3. Week 3-4'
WHEN listing_age_days BETWEEN 31 AND 60 THEN '4. Month 2'
ELSE '5. Month 3'
END AS age_bucket,
ROUND(AVG(views), 2) AS avg_views,
ROUND(median (views), 1) AS median_views
FROM
(
SELECT
s.id,
l.category,
s.day_time - toInt32 (l.published_at / 86400) AS listing_age_days,
s.views
FROM
sadb_stats_listings_stats s FINAL
JOIN sadb_listings l FINAL ON s.id = l.id
WHERE
toDate (s.day_time) >= today () - INTERVAL 3 MONTH
AND l.published_at > 0
AND s.day_time >= toInt32 (l.published_at / 86400)
AND l._peerdb_is_deleted = 0
AND l.status = 1
AND (s.day_time - toInt32 (l.published_at / 86400)) BETWEEN 0 AND 90
) t
JOIN sadb_categories c FINAL ON t.category = c.category_id
WHERE
c.name_en IN (
'Apartment for Rent',
'Villa for Sale',
'Land for Sale',
'Apartment for Sale',
'Villa for Rent'
)
GROUP BY
c.name_en,
age_bucket
ORDER BY
c.name_en,
age_bucket

Conversion rate (contacts / views) also decays over time, but less dramatically than raw views.

Listing AgeAvg ViewsAvg ContactsConversion %
Day 020.92.4211.6%
Day 239.63.378.5%
Day 726.81.806.7%
Day 1421.71.406.4%
Day 3017.21.026.0%
Day 6012.30.675.4%
Day 909.60.505.2%
MetricWeek 1Month 3Decay
Views30 avg10 avg—67%
Contacts2.3 avg0.5 avg—78%
Conversion %7.5%5.3%—29%
CategoryWeek 1Week 2Wk 3-4Mo 2Mo 3Decay
Apartment Rent8.0%7.0%6.6%6.2%6.1%—24%
Villa Rent7.2%6.1%5.8%5.6%5.6%—22%
Land Sale8.0%5.6%4.8%4.2%3.9%-51%
Apartment Sale4.5%4.2%4.3%3.8%3.9%—13%
Villa Sale4.3%3.1%3.0%2.7%2.5%-42%

Insight: Rentals maintain conversion better, Land sales have steepest decay

CityWeek 1Week 2Wk 3-4Mo 2Mo 3Decay
مكة8.7%7.8%6.7%6.6%5.1%—41%
الرياض7.9%6.7%6.4%5.9%5.5%—30%
الدمام7.5%6.7%5.9%5.3%6.3%—16%
جدة7.2%6.0%5.6%5.2%4.8%—33%
SELECT
s.day_time - toInt32 (l.published_at / 86400) AS listing_age_days,
SUM(s.views) AS total_views,
SUM(s.calls + s.msgs + s.whatsapp) AS total_contacts,
ROUND(
100.0 * SUM(s.calls + s.msgs + s.whatsapp) / NULLIF(SUM(s.views), 0),
2
) AS conversion_pct,
ROUND(AVG(s.views), 1) AS avg_views,
ROUND(AVG(s.calls + s.msgs + s.whatsapp), 2) AS avg_contacts
FROM
sadb_stats_listings_stats s FINAL
JOIN sadb_listings l FINAL ON s.id = l.id
WHERE
toDate (s.day_time) >= today () - INTERVAL 3 MONTH
AND l.published_at > 0
AND s.day_time >= toInt32 (l.published_at / 86400)
AND l._peerdb_is_deleted = 0
AND l.status = 1
AND (s.day_time - toInt32 (l.published_at / 86400)) BETWEEN 0 AND 90
GROUP BY
listing_age_days
ORDER BY
listing_age_days
SELECT
c.name_en AS category,
CASE
WHEN listing_age_days BETWEEN 0 AND 7 THEN '1. Week 1'
WHEN listing_age_days BETWEEN 8 AND 14 THEN '2. Week 2'
WHEN listing_age_days BETWEEN 15 AND 30 THEN '3. Week 3-4'
WHEN listing_age_days BETWEEN 31 AND 60 THEN '4. Month 2'
ELSE '5. Month 3'
END AS age_bucket,
SUM(views) AS total_views,
SUM(contacts) AS total_contacts,
ROUND(100.0 * SUM(contacts) / NULLIF(SUM(views), 0), 2) AS conversion_pct,
ROUND(AVG(views), 1) AS avg_views,
ROUND(AVG(contacts), 2) AS avg_contacts
FROM
(
SELECT
s.id,
l.category,
s.day_time - toInt32 (l.published_at / 86400) AS listing_age_days,
s.views,
s.calls + s.msgs + s.whatsapp AS contacts
FROM
sadb_stats_listings_stats s FINAL
JOIN sadb_listings l FINAL ON s.id = l.id
WHERE
toDate (s.day_time) >= today () - INTERVAL 3 MONTH
AND l.published_at > 0
AND s.day_time >= toInt32 (l.published_at / 86400)
AND l._peerdb_is_deleted = 0
AND l.status = 1
AND (s.day_time - toInt32 (l.published_at / 86400)) BETWEEN 0 AND 90
) t
JOIN sadb_categories c FINAL ON t.category = c.category_id
WHERE
c.name_en IN (
'Apartment for Rent',
'Villa for Sale',
'Land for Sale',
'Apartment for Sale',
'Villa for Rent'
)
GROUP BY
c.name_en,
age_bucket
ORDER BY
c.name_en,
age_bucket
SELECT
d.city_name,
CASE
WHEN listing_age_days BETWEEN 0 AND 7 THEN '1. Week 1'
WHEN listing_age_days BETWEEN 8 AND 14 THEN '2. Week 2'
WHEN listing_age_days BETWEEN 15 AND 30 THEN '3. Week 3-4'
WHEN listing_age_days BETWEEN 31 AND 60 THEN '4. Month 2'
ELSE '5. Month 3'
END AS age_bucket,
SUM(views) AS total_views,
SUM(contacts) AS total_contacts,
ROUND(100.0 * SUM(contacts) / NULLIF(SUM(views), 0), 2) AS conversion_pct
FROM
(
SELECT
s.id,
l.district_id,
s.day_time - toInt32 (l.published_at / 86400) AS listing_age_days,
s.views,
s.calls + s.msgs + s.whatsapp AS contacts
FROM
sadb_stats_listings_stats s FINAL
JOIN sadb_listings l FINAL ON s.id = l.id
WHERE
toDate (s.day_time) >= today () - INTERVAL 3 MONTH
AND l.published_at > 0
AND s.day_time >= toInt32 (l.published_at / 86400)
AND l._peerdb_is_deleted = 0
AND l.status = 1
AND (s.day_time - toInt32 (l.published_at / 86400)) BETWEEN 0 AND 90
) t
JOIN sadb_districts d FINAL ON t.district_id = d.district_id
WHERE
d.city_name IN ('الرياض', 'جدة', 'الدمام', 'مكة المكرمة')
GROUP BY
d.city_name,
age_bucket
ORDER BY
d.city_name,
age_bucket

  • Listings not converting by Day 30 are getting ~40% of peak traffic
  • Consider automated refresh prompts at Day 14 and Day 30
  • If no contacts by Week 2, listing may be overpriced
  • Sales listings (especially land) need pricing attention early
  • Rentals: High volume, maintain conversion - focus on response time
  • Land Sales: Urgency-driven buyers - price aggressively early
  • Villa Sales: Longer cycle expected - patience but monitor conversion
  • Riyadh: Fastest market, most competitive - quick response essential
  • Makkah: High initial interest but fast decay - capture early
  • Jeddah: Slower decay but lower baseline - quality over speed

  • Analysis Period: 2024-01-01 onwards (regulatory changes make earlier data incomparable)
  • View/Conversion Analysis: Last 3 months only for recency
  • Time on Market: Filtered to 1-730 days (excludes outliers)
  • day_time format: Days since Unix epoch (not Unix timestamp)
  • published_at format: Unix timestamp (seconds)