Using accounting data for quotas

Parham Beheshti p_beheshti at
Tue Feb 17 11:32:03 CET 2009

I've implemented this situation.
well, our solution was a bit more complex, we have "peak" and "off peak" times. for example weekends are "off peak".
Users have a limited traffic based on their group, say 25GB/month.
here is pretty much what i have done (simplified!):
1. add a "traffic" usage field in users table.
2. i have an "hourlytraffic" table, 1 row per online user/per hour.
3. i have a "dailytraffic" table, 1 row per online user/per day.
4. instead of plain SQL in sql module, i pass all the data to stored procedures.
5. when ever i get a new "interim-update" (every 5 minutes) i calculated the difference from sessions table. now i know how much traffic the user used in the last interim. based on the time i received the interim(off peak time or peak time) i know if i should add this traffic to usage of the user.
6. in the stored procedure, when ever a user has more usage then allowed by plan, i add a row to a "disconnect_job" table. every few minutes i disconnect sessions with COA from nas.

the system is pretty flexible, different plans with different peak/off peak times, usage limits,etc. and it is very very stable!
just to let you know how this performs.
i run national DSL subscribers on this(about 50,000 online sessions) from over 50 nases all going through one freeradius/mysql box!

few issues i ran into:

Problem 1: hourlytraffic table will get huge!!! with millions and millions of rows. you wont be able to delete any data from that table since "delete from hourly traffic where...." will lock the table for a while. 

Solution 1: Use new mysql 5.1 partitioned tables. you can partition your hourly/sessionlogs/daily tables based on months/weeks or days ... and drop an old partition instead of deleting data.

Problem 2: sometimes(very very rare) i get packets in wrong order. for example i get packet with 2GB traffic and another one with 1.9GB, if you  just substract them in your stored procedure, you end up with a negative number or if you are not using signed variables, you end up with a huge number. no idea why i get these packets from time to time:

solution 2: always make sure the packet you receive is in the right order. if it is not, drop it!

i hope this helps

-----Original Message-----
From: at on behalf of ahmed adel
Sent: Sun 2/15/2009 12:43 PM
To: FreeRadius users mailing list
Subject: Re: Using accounting data for quotas
I have implemented quota service based on Freeradius before, and I
think that it is close to what you are looking for except that in my
case there was a required action. Anyway it is normal that session
remain open for long time so if using SQL you can have a trigger on the
accounting table to update another table with a summary of the total
bandwidth used for each user and this is available for MySQL and MSSQL.

As for simultaneous you can disable that using simultaneous-use option.

Also it is normal that the updates come in different times but the trigger on the database will solve this issue.

For the traffic counters there are two approaches one is that your
network equipment supports sending what is called Giga-Word counter
which is a counter that tells you how many times the counter has rolled
over, if not you will have to handle this in your SQL statment and this
is by keeping the last update in a field in the database and on the new
update compare the new update with the previous one and if the previous
one is bigger just by simple math compensate for the different.

For the last point also the trigger on the database will solve it as you will have another table to hold the history in.

Best Regards
Ahmed Adel

From: Jonathan Gazeley <jonathan.gazeley at>
To: freeradius-users at
Sent: Friday, February 13, 2009 12:56:14 PM
Subject: Using accounting data for quotas

I'm trying to find a way to extract useful data from accounting logs to use towards a quota. I'm a bit stuck and I'm wondering if anyone has tried anything similar with success. Let me explain...

My accounting logs are sent to SQL with the inner ID. Periodically, the NAS updates the accounting record with total of upload and download during that session. I've tweaked the FR queries so they also update a new field called 'lastupdatetime'.

I want to write an hourly script that will tell me (eg in a CSV file) how much traffic has been done for each username (not necessarily each session) during the last hour. Clearly this will take some sort of hourly summary that can be compared each hour. But it is still not straightforward:

- Some sessions remain open for weeks.
- Some users have multiple simultaneous or multiple sequential sessions.
- The updates come in at different times.
- The traffic counters will roll over from time to time.
- It's not possible to query hourly on how traffic the user has used since forever, because records older than around 90 days are dropped.

Any ideas? Or am I barking up completely the wrong tree...


Jonathan Gazeley
Systems Support Specialist
ResNet | Wireless & VPN Team
Information Services
University of Bristol

List info/subscribe/unsubscribe? See


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the Freeradius-Users mailing list