Offload your Episerver Find tracking

Imagine a site with 10+ instances and a lot of visitors and search requests. The find queries are tracked, to provide data for the auto suggest, and cached.
And then… you get an error in Find: Too Many Requests.

My first thought was to increase the value for StaticallyCacheFor. But it did not have as much of an impact as I thought. After looking into how the queries are cached I found that it is cached per server/instance. So when you have 10+ instances… it does not help much. You can’t override the ICache implementation, so I have put in a feature request for that.

The next thing I noticed was that for each request that was done to Find, another one was done for the tracking. Disabling tracking was not really an option, as that would cripple the auto suggest.

So I came up with the idea to “offload” the tracking. You can implement custom tracking, see Henrik’s post. But instead of making the request immediately, I first save it to the database and have a scheduled job send the data to Find at night.

You will need a table in the DB of course, and some stored procedures. See gist for the complete sql.

CREATE TABLE [dbo].[tblFindTrackingQueue]
(
	[Id] [bigint] IDENTITY(1,1) NOT NULL,
        [TrackingId] [nvarchar](max) NOT NULL,
	[NrOfHits] [int] NOT NULL,
	[Query] [nvarchar](max) NOT NULL,
	[Tags] [nvarchar](max) NOT NULL
);
GO

CREATE PROCEDURE [dbo].[FindTrackingQueue_Save]
(
    @TrackingId NVARCHAR(max),
    @NrOfHits INT,
    @Query NVARCHAR(max),
    @Tags NVARCHAR(max)
)
AS
BEGIN
	INSERT INTO [dbo].[tblFindTrackingQueue]
           ([TrackingId]
           ,[NrOfHits]
           ,[Query]
	   ,[Tags])
     VALUES
           (@TrackingId, @NrOfHits, @Query, @Tags)
END
GO

Next I created a “FindTrackingService” that you can use to add the data to the table, delete it, etc. See gist for the complete code.

To use FindTrackingService you will need to remove “.Track()” from your query and use the following. The input you need is a “the query”, “the amount of results for the query”, “a tracking id”, and “the tags”.

IStatisticTagsHelper statisticTagsHelper = ServiceLocator.Current.GetInstance();
IFindTrackingService findTrackingService = ServiceLocator.Current.GetInstance();
string trackId = new TrackContext().Id;
IEnumerable tags = statisticTagsHelper.GetTags(false);
findTrackingService.SaveTrackingInformation("yourQuery", totalMatching, trackId, tags);

To send the data to Find I created a scheduled job that does nothing more than loop through the database records and send them to Find, pausing after every 25 requests to not get the same error I was trying to fix.

The complete solution is in a gist.

P.S. Happy New Year!

8 thoughts on “Offload your Episerver Find tracking

      1. I am thinking more from a performance perspective. I’ve seen a number of performance issues with tracking where we are waiting for that to finish. Most of our time in 50th percentile and up is waiting on tracking. There are other mitigation options, but I see how this could be useful when not needing the tracking result.

        Like

Leave a comment