Skip to content

Listing Performance Analysis

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

Executive Summary

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

Key Findings

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

1. Time on Market Analysis

Overview

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

By Category (Median Days)

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

By City (Median Days)

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)

CohortRiyadhJeddahDammam
Jan 2024516257
Jul 2024393933
Jan 2025333733
Oct 2025323530

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

Villa for Sale (Median Days by Cohort)

CohortRiyadhJeddahDammam
Jan 2024108152141
Jul 202494142164
Jan 2025186021
Oct 2025524930

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

Query: Time on Market by Category

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

Query: Time on Market by City

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

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

2. View Decay Analysis

Overview

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

Overall View Decay Pattern

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%

View Decay by Category

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%

View Decay by City

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%

Query: View Decay by Listing Age

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

Query: View Decay by Category (Bucketed)

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

3. Contact Conversion Decay Analysis

Overview

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

Overall Conversion Decay

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%

Decay Comparison

MetricWeek 1Month 3Decay
Views30 avg10 avg—67%
Contacts2.3 avg0.5 avg—78%
Conversion %7.5%5.3%—29%

Conversion by Category

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

Conversion by City

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%

Query: Conversion by Listing Age

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

Query: Conversion by Category (Bucketed)

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

Query: Conversion by City (Bucketed)

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

Business Implications

1. Listing Refresh Strategy

  • Listings not converting by Day 30 are getting ~40% of peak traffic
  • Consider automated refresh prompts at Day 14 and Day 30

2. Pricing Guidance

  • If no contacts by Week 2, listing may be overpriced
  • Sales listings (especially land) need pricing attention early

3. Category-Specific Strategies

  • 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

4. City-Specific Insights

  • 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

Data Notes

  • 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)