Tips

Watch your user

DO NOT run the hourly script as anybody but the user who will be running the cron jobs! This will result in shared memory segments being created with the wrong ownership. It's possible then that the cron jobs will not be able to clean out the shared memory (A Bad Thing).

Be careful with DaysOfWeek and HoursOfDay

You can get in a lot of trouble if you try to specify different days of the week for a campaign and its creatives. For example, suppose you set up a campaign to run M-F. You put in a creative for Tu,Th. The campaign runs for one week, at 100,000 impressions. daily_maint.php will determine that the campaign can get 20,000 per day. The creative, however, only runs Tu,Th. On Monday, it will get no impressions. Tuesday, the engine will notice this short and will try to schedule 25,000 for the campaign, which will get assigned to the creative. Wednesday, daily_maint.php will schedule 25,000 impressions to the campaign, but the creative will get nothing, and thus the campaign will not run. Thursday, the campaign will get 37,500 impressions, all of which will go to the creative. On Friday, daily_maint.php will try to schedule 37,500 impressions to the campaign, but the creative will get nothing, and thus the campaign will not run. Now our campaign is over, and we've come up 37,500 impressions short.

Best practice is to have all your creatives set to the defaults and control your days/hours at the campaign level.

If you don't have impression targets, you don't need to worry about this. You could create a campaign with default days/hours, and then have a variety of creatives that run on different days.

About clickthrough errors

If you're using IMG tagging, you'll notice in the reports and log files that there will be a certain number of clickthrough errors. This is to be expected. You will see clickthrough errors whenever a spider hits your site and follows the clickthrough link on an ad banner. Unfortunately, since clickthrough rates are generally low, these clickthrough errors often represent a large portion of the total clicks.

If you are not comfortable with the clickthrough error rates you're seeing, you might want to sift through the log files yourself to try to verify that these are legitimate errors:

More about clickthrough errors

When a client presents a cookie to the clickthrough engine, it tries to look the cookie up in the delivery table. If it fails, it then falls back to the IP address. You might wonder how you could get a cookie from the client but not be able to find an entry in the delivery table. The first explanation is obvious; if a client views an ad banner and then waits so long to click through that the entry has already been cleared from the delivery table (ClickthroughWindow preference setting).

The second explanation is not so obvious. When ad tags for two different sections (let's say sections X and Y) appear on one page, the client may request the creatives for both in parallel. Both requests come in without cookies, so the impression engine hands out two different cookies. Only the second cookie received (let's say the one given out with the ad for section Y) is kept by the client. When the clickthrough comes in for section X, the cookie is presented. However, it was not the one recorded in the delivery table for section X. Thankfully, unless the user is behind a very busy proxy server, the fallthrough to the IP address lookup will generally result in the right clickthrough. It's also worth noting that this situation can only happen the very first time somebody comes to your ad server (or whenever he clears his cookie table) and he clicks on one of the first ads he sees. Presumably this will be a fairly rare situation.

Last hour of the day

If your site's traffic profile dips at night to low levels, you might want to take advantage of that in entering your traffic profile numbers. You can enter 0 for hour 23, and use that hour entirely for making up any shortfalls during the other hours of the day. If all goes well, none of the campaigns with impression targets will be scheduled during that hour, but in the off chance that there is a shortfall in hour 22, you'll have hour 23 to make up the difference.

This strategy also reduces the chance that you might have an hour 23 shortfall on the last day of a campaign and come up short for the entire campaign.

Campaign/Creative Weights

Campaign weights are relative to other campaigns. Creative weights are relative to the other creatives within the same campaign. The final weight that a creative gets when it is scheduled is

Final Weight = Campaign Weight * (Creative Weight / Sum of all Creative Weights in Campaign) * 100

This formula preserves the overall weight of the campaign when the creatives are scheduled. Here's an example:

Campaign, Creative Weights
Campaign A: 10
Campaign A, Creative 1: 20
Campaign A, Creative 2: 5

Campaign B: 20
Campaign B, Creative 3: 10

Final Weights
Creative 1: 10 * (20 / 25) * 100 = 800
Creative 2: 10 * (5 / 25) * 100 = 200
Creative 3: 20 * (10 / 10) * 100 = 2000

Now the ratio of Creative 1 to Creative 2 is still 4:1. The ratio of Campaign A to Campaign B is still 1:2 (800 + 200 for Campaign A and 2000 for Campaign B).

This weighting works very well if all the creatives are assigned to the same section(s). But one scenario in which this weighting can cause some difficultly is if you have one campaign with a single creative running on many sections and another campaign with many creatives each running on one section. If you want to balance the two campaigns so that each gets roughly the same number of impressions, you may find that you have to make some adjustments. Here's an example: Campaign, Creative Weights
Campaign A: 10
Campaign A, Creative 1: 10
Campaign A, Creative 2: 10
Campaign A, Creative 3: 10
Campaign A, Creative 4: 10
Campaign A, Creative 5: 10

Campaign B: 10
Campaign B, Creative 6: 10

Final Weights
Creative 1: 10 * (10 / 50) * 100 = 200
Creative 2: 10 * (10 / 50) * 100 = 200
Creative 3: 10 * (10 / 50) * 100 = 200
Creative 4: 10 * (10 / 50) * 100 = 200
Creative 5: 10 * (10 / 50) * 100 = 200
Creative 6: 10 * (10 / 10) * 100 = 1000

Now suppose that creatives 1-5 each run on a single section 1-5, respectively. Creative 6 runs on all 5 sections. Since the two campaigns have equal weights, you might expect their creatives to run with the same frequency. But they won't. Creative 6 will run 5 times as often as the other combined. When the delivery engine makes its decision as to which creative to run, it compares the weights of all creatives assigned to run on the given section. In each case, it will be comparing a creative with weight 200 to one with a weight of 1000. Creative 6 will win 5/6 (1000/1200) times.

To balance the campaigns more evenly, you might want to compensate so that Campaign A gets a weight of 50 (multiply the original campaign weight by the number of creatives).

Note that this method gets considerably more complex if you schedule the creatives for overlapping sections (or if the sections covered by Campaign A are not the same as those for Campaign B). Reliable balancing may be impossible in such cases.

Importing Campaigns in Progress

If you are setting up campaigns that are currently running on another ad server, you may need to do some tweaking in the database to get the campaigns to look right on an invoice. This advice really only applies if the campaign has a non-zero Impressions Guaranteed value.

Suppose you have a six-month campaign that gets 100,000 impressions per month running on some other ad server. Halfway through the campaign, you want to move the campaign from the old ad server to OASIS. You should set up the campaign exactly like it appears on the old server (with the original start/end dates and impression target). Don't make the campaign active in OASIS yet. You then need to figure out exactly how many impressions have been delivered thus far on the old server. Get the CampaignID for the OASIS campaign (you can see it in the URL on the campaign edit page). Then go into MySQL and run this query on the oasis database:

update Campaigns set ImpressionsDelivered=300000 where CampaignID=36

(Of course, you'll have a different CampaignID and impression number). You'll also need to do this for a creative in the campaign. If you only have one creative in the campaign, you can do it quite easily:

update Creatives set ImpressionsDelivered=300000 where CampaignID=36

Otherwise, you'll need to have the CreativeIDs of the creatives. You can pick one of the creatives and assign all the impressions to that creative. (If you have specific Impressions Guaranteed values for creatives in the campaign, you'll need to be judicious about which creative you give the impressions to, or maybe you can get actual breakdowns from your old server).

If by some chance, you have to do this on an active campaign, you can still do it, but keep in mind that ImpressionsDelivered may not be zero anymore (and the hourly maintenance script might need to write to this record, so you have to be careful when you do this; it's best to avoid the minutes right before and after the top of the hour). The query for an active campaign would be this:

update Campaigns set ImpressionsDelivered=ImpressionsDelivered+300000 where CampaignID=36

Be careful with Exclusives

Your best bet if you are using exclusive assignments is to use it with campaigns that do not have impression targets. There are two types of problems that can occur if you use exclusive assignments for campaigns with impression targets.

First, your campaign may need more impressions than can be delivered by the section to which you assigned it exclusively. You can compensate for this by assigning the campaign to other sections in addition to the exclusive assignment.

Second, the section may get more impressions than the campaign needs. When the campaign hits its hourly target, blank ads will be served. This problem may be compounded if you've assigned the campaign to other sections, as some of its hourly target impressions will be delivered on the other sections, leaving even fewer for the exclusive assignment. A workaround for this situation is to assign another campaign (perhaps a house campaign) with no impression target to the section as exclusive. Both campaigns will run on the section (of course, the campaign with an impression target will get its impressions first). This won't be a true "exclusive" for either campaign, but it will avoid having blank banners run.

Stopping MySQL

In general, you don't want to stop MySQL while you're live. But sometimes a system administrator may find it necessary to do so.

Do NOT stop it while one of the maintenance scripts is running. This will cause you to lose an hour's worth of stats and wreak havoc on the scheduler, among other things.

If you stop MySQL and you're using oasisi.php to deliver your banners, you will experience some problems. Banners will continue to be delivered, but they won't go into the Delivery table, so if users try to click through, they won't get redirected properly.

Note that since the Delivery table is stored in RAM, when you restart MySQL, it will have a completely cleaned out Delivery table.

If you're using oasisi-e.php to deliver banners, you won't have any problems, since it does not depend on the Delivery table.