Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

MThomas's avatar

Cache until a certain time

How can I cache a variable until a certain time. Let's say I have an database record that is updated every 15 minutes. On the first user request the variable is loaded from the database and cached. And once it is cached I like to 'remember' the values until 'updated_at' + 15 min is reached.

0 likes
11 replies
unitedworx's avatar

You can use laravel caching to do this e.g. to cache your query every 15 minutes you can do the following

if (($myquery = Cache::get('myvars.cache')) === null)
{
    $myquery = ......; //query to get the vars
    Cache::put('myvars.cache', $myquery, 15);
}

Now if you want to cache you vars until they are changed the simply cache them forever and add a listener that clears the cache when you model is updated or saved!

if (($myquery = Cache::get('myvars.cache')) === null)
{
    $myquery = ......; //query to get the vars
    Cache::forever('myvars.cache', $myquery);
}

<?php use Illuminate\Support\ServiceProvider; class MyCacheServiceProvider extends ServiceProvider { public function register() { $this->app['events']->listen('eloquent.saving: MyModel', function($model) { Cache::forget('myvars.cache'); }); } } )
MThomas's avatar

@unitedworx Thanks, but that is not what I want to realize.

I know how to cache the data for 15 minutes, that is not the problem. What I want is that once a user request the data the data is retrieved from the database, and based on the updated_at value I want to cache the data for updated_at + 15 minutes (so if the user request to view the database entry is made at 2014-10-21 10:17:12 and updated_at value is 2014-10-21 10:16:12, I want the data to be cached until 2014-10-21 10:31:12. at that time a new entry will have been added to the database with the most actual data.

Using an event listener will be overkill. It is highly likely that the user will not visit the site for hours or even days but the data will still change. It feels wrong to update the values every 15 minutes, even if they are not retrieved.

unitedworx's avatar

Not sure why you want to cache it for 15 minutes after the updated_at time. Can you explain a bit better why you want to do it like this?

In your above example there is no point caching it since your cache is expired already! In you above example the cache would be usefully only for 15 minutes of the record being updated and wont be cached after that.

Not sure if I understood it wrong or you explained it wrong but it does not seem to make sence what you are trying to do :)

MThomas's avatar

@unitedworx ok sorry, made a stupid typo, fixed that and updated my prev post. that might help.

bashy's avatar

Not sure why you want to do the updated_at+ 15 mins. Maybe explain what this data is? There will be another way to do it I'm sure.

unitedworx's avatar
Level 8

Ok got it! If I understand correctly your data is updated every 15 minutes and you want to cache it to increase performance but not after the 15 minutes since it changes and you want to make sure you have fresh data!

if (($myquery = Cache::get('mydata.cache')) === null)
{
    $mydata = ......; //query to get the data

    // calculate time difference in minutes using carbon
    $updated_at = $mydata->updated_at;
    $requested_at = Carbon::now();
    $diffInMinutes = $updated_at ->diffInMinutes($requested_at);

    //only cache our data if time diff is less that 15 min for that time
    If ( ($diffInMinutes>=0) && ($diffInMinutes<=15)){
        Cache::put('mydata.cache', $myquery, $diffInMinutes);
    }
}
1 like
Shovels's avatar

Can you...

  1. Retrieve the data (as the cache will be empty)
  2. Get the updated_at value - calculate the the difference between now() and updated_at + 15 mins
  3. Set the cache based on the time returned from step 2

All users should then get the cached data until it becomes invalid. This way it won't matter when the cache gets created - It'll never exceed updated_at + 15 mins.

(Or should the cache be on a per-user basis??)

MThomas's avatar

@bashy I'll try to explain the flow.

Every 15 minutes an artisan command is run to collect data from an external source. This is done on behalf of the user for projects he or she created.

This data is processed and for each project a short summary is stored in an MongoDB database (for example the current storage size, number of items stored in total and number of items processed).

On several pages on the website this information is displayed to the user. On a project page only the latest entry for this project is retrieved from the database. However on the users dashboard page an aggregated storage size is shown. To calculate this, for each project the latest entry (of the storage size, count etc) is retrieved and the sum is calculated.

Every time (read: every 15 minutes) a new entry is added to the database with an updated_at field to indicate the time this entry was created (I named it updated_at but it could also be update or at or created_at). So once a user retrieves the data from the database this data won't change until update_at + 15 min is reached. So for this period I like to cache the data in order to allow the user to see the most recent information once the new artisan command is run.

At first I planned on caching the variable for each project in the artisan command. But this felt a bit weird, it is higly possible that the user won't access the website for hours or even days, but in order to increase performance I want to cache the values when is visits the site.

Hope this helps.

MThomas's avatar

@unitedworx damn I feel so stupid that I did not come up with that extremely simple solution :(.

Many thnx!!!

unitedworx's avatar

Np, MThomas glad this helped!

if this is per user I guess you will need to append the id of the user at the end of the cache name.

1 like

Please or to participate in this conversation.